Reputation: 1782
Trying to use filegetcsv
to parse a CSV file and do stuff with it, using the following code found all over the Internet, including the PHP function definition page:
if (($handle = fopen("test.csv", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
print_r($data);
}
fclose($handle);
}
But the code gives me an infinite loop of warnings on the $data =
line:
PHP Warning: fgetcsv() expects parameter 1 to be resource, boolean given in...
I know the file's not too big, or malformed, because I kept shrinking the original file to see if that was a problem and finally just created a custom file in Notepad with nothing more than two lines like:
Value1A,Value1B,Value1C,Value1D
Still looping and giving no data. Here's the full code I'm working with now (using a variable that's greater than the number of lines so I can prove that it would loop infinitely without actually giving my server an infinite loop)
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);
}
So I really have two questions.
1) What could I possibly be overlooking that is causing this loop? I'm half-convinced it's something really "face-palm" simple...
2) Why is the recommended code for this function something that can cause an infinite loop if the file exists but there is some unknown problem? I would have thought the purpose of the !== FALSE
and so forth would be to prevent that kind of stuff.
Upvotes: 1
Views: 3873
Reputation: 8979
$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);
}
Try given Code Snippet once,because as i have noticed you are missing some important things in your code.
Upvotes: 0
Reputation: 437376
There's no question about what's going on here: the file is not opened successfully. That's why $handle
is a bool
instead of a resource (var_dump($handle)
to confirm this yourself).
fgetcsv
then returns null
(not false
!) because there's an error, and your test doesn't pick this up because you are testing with !== false
. As the documentation states:
fgetcsv() returns NULL if an invalid handle is supplied or FALSE on other errors, including end of file.
I agree that returning null
and false
for different error conditions is not ideal, and furthermore that it's against the precedent established by lots of other functions, but that's just how it is (and things could be worse). As things stand, you can simply change the test to
while ($data = fgetcsv($handle, 1000, ","))
and it will work correctly in both cases.
Update:
You are the victim of assignment inside an if
condition:
if ($handle = fopen($_SERVER['DOCUMENT_ROOT'].'/tmp/test-csv-file.csv', 'r') !== FALSE)
should have been
// wrap the assignment to $handle inside parens!
if (($handle = fopen($_SERVER['DOCUMENT_ROOT'].'/tmp/test-csv-file.csv', 'r')) !== FALSE)
I 'm sure you understand what went wrong here. This is the reason why I choose to never, ever, make assignments inside conditionals. I don't care that it's possible. I don't care that it's shorter. I don't even care that sometimes it's quite less "elegant" to write the loop if the assignment is taken out. If you value your sanity, consider doing the same.
Upvotes: 6