如何使用 php 替换 CSV 文件中一行中的 1 个值?

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

所以这是我非常简单和基本的帐户系统(只是一个学校项目),我希望用户能够更改他们的密码。但我不确定如何在保持所有其他值不变的情况下仅替换一行中的密码值。

CSV 文件:

ID,Username,Email,DateJoined,Password,UserScore,profilePics
1,Test,Test@Test.com,03/12/2014,Test,10,uploads/profilePics/Test.jpg
2,Alfie,Alfie@test.com,05/12/2014,1234,136,uploads/profilePics/Alfie.png

PHP: ("cNewPassword" = 确认新密码)

<?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!");
}
?>

您需要一个 3 步过程来执行此操作(创建 3 个循环,可以优化为 1 或 2 个循环):

  1. 加载相关数据到内存
  2. 更新所需数据
  3. 将数据保存到文件

祝你好运! :)

PS。此外,您的密码永远不应以明文形式存储,无论是内存(会话)还是磁盘(csv),请使用 hasing 函数!

您必须以读取模式打开文件,以写入模式打开一个临时文件,将修改后的数据写入其中,然后是 delete/rename 个文件。我建议尝试设置一个真正的数据库并使用它工作,但如果你要使用 csv,代码应该看起来或多或少像这样:

$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

希望对您有所帮助。

我的建议是我的一个小函数,它将把你的数据库数据变成一个你可以修改的数组,然后 return 到原始状态:

使用这组函数,您只需精确地确定每个 row/row 数据是如何分离的。

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;
}

让我们指出我在你的数据库示例中尝试了这些,即使在测试它自己的结果时它仍然有效,例如:dbToArray(arrayToDb(dbToArray())) 多次。

希望有所帮助。如果我能更清楚,请不要犹豫。 :)

干杯,