【问题标题】:warning: fputcsv() expects parameter 2 to be array, boolean. when writing to new csv file. php警告:fputcsv() 期望参数 2 是数组,布尔值。写入新的 csv 文件时。 php
【发布时间】:2018-07-27 23:47:55
【问题描述】:

我有一个名为 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,3432

我想删除 csv 文件中的选定行。为此,我将简单地将 csv 文件中我不想删除的 2 行复制到 new_employee_data.csv 文件并删除旧的。

<?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(!feof($dataFile)) {
    $csv = fgetcsv($dataFile); //read a line from the CSV file
    //$csv = [ANE WILLIAMS,6/8/1998,55846874E,4323];
    //add check to remove row
    print_r($csv);
        if($csv[2] == '55846874E') continue; //skip to next itteration

        fputcsv($outFile, $csv);
}

fclose($dataFile);
fclose($outFile);
?>

上面的代码将$dataFile的内容逐行写入$outFile,如果第三列='55846874E',它将跳过写入该行。 csv 数组包含 employee_data.csv 文件中的行。

$csv 数组中的元素如下。

Array ( [0] => JANE WILLIAMS [1] => 6/8/1998 [2] => 55846874E [3] => 4321 )
Array ( [0] => PETER JONES [1] => 15/01/1982 [2] => 56897547Q [3] => 1234 ) 
Array ( [0] => JAMES O'BRIEN [1] => 09/05/2001 [2] => 25689514W [3] => 8475 ) 

它删除文件的第一行 - JANE WILLIAMS,6/8/1998,55846874E,4323

现在 new_employee_data.csv 中是两条未删除的记录。

"PETER JONES",15/01/1982,56897547Q,1234
"JAMES O'BRIEN",09/05/2001,25689514W,8475

这正是我想要它做的,但是当我在浏览器中运行它时收到了这个警告:

fputcsv() 期望参数 2 是数组,第 25 行给出的布尔值

fputcsv($outFile, $csv); 有问题,我不知道为什么,有什么解决方法的建议吗?

【问题讨论】:

  • 根据 php 文档:fgetcsv() returns NULL if an invalid handle is supplied or FALSE on other errors, including end of file. 这告诉我它很可能已到达文件末尾
  • 您好,再次感谢您将这个问题作为一个单独的问题发布,我正在回家的路上,不得不跑步......哈哈抱歉

标签: php arrays file csv


【解决方案1】:

我会改变while循环所以而不是

while(!feof($dataFile)) {
    $csv = fgetcsv($dataFile); 

喜欢这个

while(false !== ($csv = fgetcsv($dataFile))){

您可以在 PHP 网站here 上查看此用法的示例

可能发生的情况是文件末尾有一个额外的return,所以feof 没有捕捉到它,然后你得到fgetcsv 的布尔值false。例如像这样(其中 \n 是一个新行):

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

所以我们可以将这些组合起来(这样你就不需要 while 循环下的那行了),然后从我们执行循环条件的同一个地方获取数据,这样当它返回 false 时,它​​就会放弃循环。重要的是要注意 = 的数量,因为单个是赋值,!== 是严格的类型比较。所以我们可以把它分解一下,用英语解释一下。

  • 拉一行并使用 fgetcsv 将 $csv 设置为它的值来处理它,括号优先
  • 如果 $csv 为布尔值 false,则循环条件为 false 并结束。所以基本上 如果 false(boolean) 不等于 fgetcsv($dataFile) 的结果,那么它是真的,否则它是假的

它的工作原理基本上是这样的

while($csv = fgetcsv($dataFile)){

我倾向于喜欢长手版本,因为它更容易看出我们是在分配而不是比较。例如,您可以看一下上面的版本,然后认为它应该是== 而不是=,所以第一个版本只是让它更明显一点。将false 放在左侧基本上是出于同样的原因(而且因为它本质上是一个常数,所以将它放在左侧可以避免像下面false = $csv 这样的错误不会起作用)。

= 放在某个条件中实际上可能是更难找出的错误之一,因为它完全合法。因此,在进行比较时,将函数调用和常量放在左侧是一种“专业提示”。

希望有帮助!

【讨论】:

  • 这是我的文件中的一个问题,这就是它无法正常工作的原因!,你的逻辑是正确的,非常感谢,很大的帮助。
  • 当然,过去 5 年我每天都使用 CSV 文件,我现在使用 SplFileObject 类,但几乎相同的差异。我只是喜欢这个类,因为它具有寻线功能,对于具有动态标题数量的文件,它可能会很好,因为您可以这样做$fileObj-&gt;seek($num_headers)
猜你喜欢
  • 2015-02-23
  • 1970-01-01
  • 2016-09-27
  • 1970-01-01
  • 1970-01-01
  • 2013-08-30
  • 1970-01-01
  • 1970-01-01
  • 2015-03-12
相关资源
最近更新 更多