filegetcsv导致无限循环

时间:2011-12-07 17:24:27

标签: php csv fgetcsv

尝试使用filegetcsv解析CSV文件并使用以下代码执行操作,使用以下代码在整个Internet上找到,包括PHP function definition页面:

if (($handle = fopen("test.csv", "r")) !== FALSE) {
    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
        print_r($data);
    }
    fclose($handle);
}

但是代码在$data =行上给了我一个无限循环的警告:

PHP Warning: fgetcsv() expects parameter 1 to be resource, boolean given in...
  1. 我知道我打开的文件是一个有效的文件,因为如果我在文件名中添加一个虚拟字符,我会得到一个不同的错误而且没有循环。
  2. 该文件位于具有完全权限的文件夹中。
  3. 我没有使用Mac上的Excel生成的CSV(there's a quirky error there
  4. PHP版本5.1.6,因此功能
  5. 应该没有问题
  6. 我知道文件不是太大或者格式不正确,因为我一直在缩小原始文件以查看是否存在问题,最后只是在记事本中创建了一个自定义文件,其中只有两行:

    Value1A,Value1B,Value1C,Value1D

  7. 仍然循环并且不提供数据。这是我正在使用的完整代码(使用大于行数的变量,因此我可以证明它会无限循环而不会实际上给我的服务器一个无限循环)

    if ($handle = fopen($_SERVER['DOCUMENT_ROOT'].'/tmp/test-csv-file.csv', 'r') !== FALSE) {
        while ((($data = fgetcsv($handle, 1000, ',')) !== FALSE) && ($row < 10)) {
            print_r($data);
            $row++;
        }
        fclose($handle);
    }
    

    所以我真的有两个问题。

    1)我可能忽略了什么导致这个循环?我半信半疑,这真的是“面子”简单......

    2)为什么这个函数的推荐代码会导致无限循环,如果文件存在但存在一些未知问题?我原以为!== FALSE等等的目的就是防止那种东西。

2 个答案:

答案 0 :(得分:6)

毫无疑问,这里发生了什么:文件未成功打开。这就是为什么$handlebool而不是资源(var_dump($handle)来自己确认)的原因。

fgetcsv然后返回null(不是false!),因为出现了错误,并且您的测试没有选择,因为您正在使用!== false进行测试。正如文档所述:

  

如果提供了无效句柄或FALSE,则fgetcsv()返回NULL   其他错误,包括文件结束。

我同意为不同的错误条件返回nullfalse并不理想,而且它违背了许多其他函数建立的先例,但这就是它的原因(以及事物{ {3}} could be)。事实上,您可以简单地将测试更改为

while ($data = fgetcsv($handle, 1000, ","))

它在两种情况下都能正常工作。

<强>更新

您是if条件内作业的受害者:

if ($handle = fopen($_SERVER['DOCUMENT_ROOT'].'/tmp/test-csv-file.csv', 'r') !== FALSE)

应该是

// wrap the assignment to $handle inside parens!
if (($handle = fopen($_SERVER['DOCUMENT_ROOT'].'/tmp/test-csv-file.csv', 'r')) !== FALSE)

我相信你明白这里出了什么问题。这就是为什么我选择永远不会在条件中进行分配的原因。我不在乎这是可能的。我不在乎它更短。我甚至不关心有时候,如果取消分配,编写循环就不那么“优雅”了。如果你重视自己的理智,可以考虑做同样的事情。

答案 1 :(得分:1)

            $row = 1;
            if (($handle = fopen($_FILES['csv-file']['tmp_name'], "r")) !== FALSE) {
                $data = fgetcsv($handle , 1000 , ",");
                while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {


                    $num = count($data);
                    echo "<p> $num fields in line $row: <br /></p>\n";
                    $row++;
                    for ($c=0; $c < $num; $c++) {
                        echo $data[$c] . "<br />\n";
                    }
                }
                fclose($handle);
            }

尝试一次给定的代码段,因为我注意到您在代码中缺少一些重要的东西。