【问题标题】:How to overwrite a csv file. PHP如何覆盖 csv 文件。 PHP
【发布时间】:2018-02-16 19:34:07
【问题描述】:

我昨天才开始使用 PHP,所以请原谅我的代码不佳。

我有一个名为 employee_data.csv 的 csv 文件。它包含格式如下的员工记录。

JANE WILLIAMS,6/8/1998,55846874E,4323
PETER JONES,15/01/1982,56897547Q,1234
JAMES O'BRIEN,09/05/2001,25689514W,8475 

员工显示在浏览器的表单上,每行包含员工详细信息,并且表格每行旁边都有一个删除按钮。当用户选择给定员工旁边的删除按钮时,选定的员工将从表单和employee_data.csv 文件中删除,并且新表单将显示而没有删除的员工。

删除表格

我想删除 csv 文件中的选定记录,但在我担心删除部分之前,我只想弄清楚如何用具有相同详细信息的新 employee_details.csv 覆盖 employee_details.csv。

我也想实现这个

1. 将employee_data.csv 文件的内容分解为字符串。
2.将字符串的内容分解成一个数组。
3.删除employee.data.csv
4.创建一个新的employee_data.csv 文件。
5.将数组的内容写入新的employee_data.csv文件
6.将新文件中的员工记录输出到一个表中,每行包含一条员工记录。

$group 数组是一个对象数组,其中每个对象都是来自 employee_data.csv 文件的员工记录。

<?php 
$dataFile = fopen("persistence/employee_data.csv", "r") or die("Unable to open file!");
$i=0;  //index for the array
while(!feof($dataFile)) {
  $csv=fgets($dataFile); //read a line from the CSV file
  if(!feof($dataFile)){ //make sure not at end
	  $employeeProperties=explode(",",$csv); //parse values to an array
          
          
        
        $group[$i]=new Employee($employeeProperties[0],$employeeProperties[1],$employeeProperties[2],$employeeProperties[3]);//create new person objects
	  $i++;
  } 
}
fclose($dataFile); //close the data file
?>

然后我将 $group 数组的内容分解为字符串,然后将字符串分解为字符串数组。

<?php
$str = implode(array_map(function($x) { return $x->get_employeeName() . $x ->get_dob()  
        .$x->get_PPSN() .$x->get_PIN().","; }, $group));
echo $str;   //implode file objects to string

$parts = explode(',' , $str);  //explode to string array
print_r($parts);
?>

$str 中的内容 - JANE WILLIAMS6/8/199855846874E4321 ,PETER JONES15/01/198256897547Q1234 ,JAMES O'BRIEN09/05/200125689514W8475

字符串 $parts 数组的内容 ([0] => JANE WILLIAMS6/8/199855846874E4321 2 => PETER JONES15/01/198256897547Q1234 2 => JAMES O'BRIEN09/05/200125684 3] =>)

然后我删除了原始的employee_data.csv,创建了一个新的employee_data.csv,并将字符串数组写入了csv 文件。

<?php
$file_Path = 'persistence/employee_data.csv';

if(file_exists($file_Path))
    {
        unlink($file_Path);    //delete file
        echo 'File Deleted';
    }else{
        echo 'File Not Exist';
    }
    
    $csv_handler = fopen ('persistence/employee_data.csv','w'); //new file
    fwrite ($csv_handler,$csv);
    fclose ($csv_handler);
    
    $filename = 'persistence/employee_data.csv';
   if (file_exists($filename)) {
    $datafile = fopen('persistence/employee_data.csv', 'w'); //write to new file
    fputcsv($datafile, $parts," ",chr(0)); 
    fclose($datafile);
   }
?>

这就是我希望新的employee_data.csv 文件的内容看起来的样子。
简·威廉姆斯,6/8/1998,55846874E,4321
彼得·琼斯,15/01/1982,56897547Q,1234
詹姆斯·奥布莱恩,09/05/2001,25689514W,8475

相反,它看起来像。
简·威廉姆斯6/8/199855846874E4321
, 彼得·琼斯 15/01/198256897547Q1234
, JAMES O'BRIEN09/05/200125689514W8475
,

在新的 csv 文件中现在有 4 条记录,最后一条不包含任何内容,我不确定为什么要添加它。我想在名称、dob 和 ppsn 后面加一个逗号。每条记录的最后 4 位数字是一个 pin。

是否有更高效的方法来覆盖 csv 文件?有什么方法可以实现我想要实现的目标吗?在过去的一个小时里,我一直在搞乱新文件的格式,这是迄今为止我想出的最好的。

注意:我必须更新对我的项目中的 csv 文件所做的任何更改,因此如果我从 csv 文件中删除员工记录,我需要一个新的或覆盖的 csv 文件,而没有删除的员工。

【问题讨论】:

  • 而不是 fgets 使用 fgetcsvfputcsv,在数据包含逗号并且可能带有新行的情况下使用 $parts = explode(',' , $str); 将失败,这两种情况都由内置 csv 函数,例如 data,"row with, comma", otherstuff,如果你用 explode 拆分它,你会得到 4 列,如果你使用 fgetcsv,你会得到 3

标签: php file csv


【解决方案1】:

例如,您使这种方式变得更加困难,例如

<?php 
$dataSrc = "persistence/employee_data.csv";
$dataDest = "persistence/new_employee_data.csv";

$dataFile = fopen($dataSrc, "r") or die("Unable to open file!");
$outFile = fopen($dataDest, "w") or die("Unable to open file!");

$i=0;  //index for the array
while(false !== ($csv = fgetcsv($dataFile))) {
    //$csv = [ANE WILLIAMS,6/8/1998,55846874E,4323];
    //add check to remove row
    if($csv[2] == '55846874E') continue; //skip to next itteration

    fputcsv($outFile, $csv);
}

fclose($dataFile);
fclose($outFile);

//rename($dataDest, $dataSrc); //rename dest to the source name, this will overwrite $dataSrc with $dataDest and remove $dataDest

没有结束标签,没有爆炸,没有垃圾。

这应该(理论上)将$dataFile 的内容逐行写入$outFile,如果第三列='55846874E',它将跳过写入该行。

例如,通过使用rename,我们可以一次性删除旧文件,删除新文件并将新文件重命名为旧文件。

【讨论】:

  • 感谢您的建议,我确实过于复杂了!新文件被删除,没有在 new_employee_data.csv 中完美格式化的已删除记录,但是我收到一个错误“fputcsv() 期望参数 2 是数组,在第 24 行给出布尔值”,这是这一行 fputcsv($outFile, $csv);
  • 好的,我更新了while循环。如果文件末尾有一个空行,就会发生这种情况。所以文件没有完成,但是没有csv数据。所以在这种情况下,$csv 可能是假的,所以我们只是在循环中使用它,这样它就会退出循环。在进入循环之前,获取 false 的 csv 数据,然后尝试将其放入 fputcsv 中,因为它是布尔值而不是数组。
  • 这是有道理的,但是我仍然遇到同样的错误 - fputcsv() 期望参数 2 是数组,在第 24 行给出布尔值。$csv 数组中的内容始终是第二个无论 if 语句中的内容如何,​​文件 "PETER JONES",15/01/1982,56897547Q,1234 中的行。因此 "PETER JONES",15/01/1982,56897547Q,1234 是唯一可以写入 new_employee_data 文件的文件。
  • 这很奇怪,很难测试,因为显然我无法打开文件,但它应该像 while 循环一样工作,你可以在 PHP 文档中看到相同类型的设置页面,就在这里php.net/manual/en/function.fgetcsv.php
  • 最后一件事,您使用的是什么操作系统?如果它是一台 Mac 有时会导致 fgetcsv 函数的行尾出现问题,通常只在较旧的 Mac 上,它应该可以很好地处理 windows 和 linux,只要那里没有奇怪的字符(比如来自 MsWord 的弯引号) 还要确保你在这里有一个 = while(false !== ($csv = fgetcsv($dataFile))) 而不是 $csv == fgetcsv( ...) 单个 = 是分配双倍是比较
猜你喜欢
  • 2020-08-06
  • 1970-01-01
  • 2013-12-28
  • 2021-11-11
  • 2018-03-08
  • 1970-01-01
  • 1970-01-01
  • 2013-05-20
  • 1970-01-01
相关资源
最近更新 更多