Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I replace 1 value within a row in a CSV file using php?

Tags:

php

csv

So this is my very simple and basic account system (Just a school project), I would like the users to be able to change their password. But I am unsure on how to just replace the Password value within a row keeping all the other values the same.

CSV File:

ID,Username,Email,DateJoined,Password,UserScore,profilePics
1,Test,[email protected],03/12/2014,Test,10,uploads/profilePics/Test.jpg
2,Alfie,[email protected],05/12/2014,1234,136,uploads/profilePics/Alfie.png

PHP: ("cNewPassword" = confirm new password)

<?php
session_start();
if(empty($_POST['oldPassword']) ||  empty($_POST['newPassword']) || empty($_POST['cNewPassword'])) {
    die("ERROR|Please fill out all of the fields.");
} else {
    if($_POST['newPassword'] == $_POST['cNewPassword']) {
        if ($_POST['oldPassword'] == $_SESSION['password']) {

            $file = "Database/Users.csv";
            $fh = fopen($file, "w");
            while(! feof($file)) {
                $rows = fgetcsv($file);
                if ($rows[4] == $_POST['oldPassword'] && $rows[1] == $_SESSION['username']) {
                    //Replace line here
                    echo("SUCCESS|Password changed!");
                } 
            }
            fclose($file);
        }
        die("ERROR|Your current password is not correct!");
    }
    die("ERROR|New passwords do not match!");
}
?>
like image 661
Alfie B Avatar asked Jan 04 '15 16:01

Alfie B


People also ask

How do I count the number of rows in a CSV file in PHP?

Method #1: Parsing the entire CSV file at once using PHP This first method uses the file() function to read the contents of the file into an array, from which the count() method can be used to derive the line count: $linecount = count(file('filename. csv')); Reading an entire file into memory just to get a line count?


2 Answers

You'll have to open file in read mode, open a temporary one in write mode, write there modified data, and then delete/rename files. I'd suggest trying to set up a real DB and work using it but if you're going for the csv, the code should look like more or less like this:

$input = fopen('Database/Users.csv', 'r');  //open for reading
$output = fopen('Database/temporary.csv', 'w'); //open for writing
while( false !== ( $data = fgetcsv($input) ) ){  //read each line as an array

   //modify data here
   if ($data[4] == $_POST['oldPassword'] && $data[1] == $_SESSION['username']) {
      //Replace line here
      $data[4] = $_POST['newPassword'];
      echo("SUCCESS|Password changed!");
   }

   //write modified data to new file
   fputcsv( $output, $data);
}

//close both files
fclose( $input );
fclose( $output );

//clean up
unlink('Database/Users.csv');// Delete obsolete BD
rename('Database/temporary.csv', 'Database/Users.csv'); //Rename temporary to new

Hope it helps.

like image 193
acontell Avatar answered Oct 09 '22 09:10

acontell


My suggestion is a little function of mine which will turn your database data into an array which you can modify and then return to original state:

With this set of function, you simply have to precise how each row/row data are separated.

function dbToArray($db, $row_separator = "\n", $data_separator = ",") {
    // Let's seperator each row of data.
    $separate = explode($row_separator, $db);

    // First line is always the table column name:

    $table_columns =
    $table_rows = array();

    foreach ($separate as $key => $row) {
        // Now let's get each column data out.
        $data = explode($data_separator, $row);

        // I always assume the first $row of data contains the column names.
        if ($key == 0)
            $table_columns = $data;
        else if ($key > 0 && count($table_columns) == count($data)) // Let's just make sure column amount matches.
            $table_rows[] = array_combine($table_columns, $data);
    }


    // Return an array with columns, and rows; each row data is bound with it's equivalent column name.
    return array(
        'columns' => $table_columns,
        'rows' => $table_rows,
    );
}

function arrayToDb(array $db, $row_separator = "\n", $data_separator = ",") {
    // A valid db array must contain a columns and rows keys.
    if (isset($db['columns']) && isset($db['rows'])) {
        // Let's now make sure it contains an array. (This might too exagerated of me to check that)
        $db['columns'] = (array) $db['columns'];
        $db['rows'] = (array) $db['rows'];

        // Now let's rewrite the db string imploding columns:
        $returnDB = implode($data_separator, $db['columns']).$row_separator;

        foreach ($db['rows'] as $row) {
            // And imploding each row data.
            $returnDB .= implode($data_separator, $row).$row_separator;
        }

        // Retunr the data.
        return $returnDB;
    }

    // Faaaaaaaaaaaail !
    return FALSE;
}

Let's just point out I tried these with your db example, and it works even when tested on it's own results such as : dbToArray(arrayToDb(dbToArray())) multiple times.

Hope that help. If I can be clearer don't hesitate. :)

Cheers,

like image 32
cram2208 Avatar answered Oct 09 '22 08:10

cram2208