1

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...
  1. I know the file I'm opening is a valid file, because if I add a dummy character to the file name I get a different error and no loop.
  2. The file is in a folder with full permissions.
  3. I'm not using a CSV generated by an Excel on Mac (there's a quirky error there)
  4. PHP version 5.1.6, so there should be no problem with the function
  5. 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.

asked Dec 7, 2011 at 17:24
2
  • And that's an exact copy/paste of your code, you didn't retype it by hand? Commented Dec 7, 2011 at 17:31
  • I copied and pasted around some comments I had, so I just copied and pasted the whole thing and removed the comments in case my original had an error. Commented Dec 7, 2011 at 17:33

2 Answers 2

6

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.

answered Dec 7, 2011 at 17:26
Sign up to request clarification or add additional context in comments.

4 Comments

OK, so basically I need to stop looking for obscure fgetscv problems and investigate why my fopen isn't doing what I'm expecting? (I'm successfully using fopen on other scripts so I can go down that route)
@joshuahedlund: Yes. file_exists and is_readable might help. However, you should have already received an E_WARNING if fopen failed. Is error_reporting on (it should be)?
@joshuahedlund: On the other hand, it turns out that you simply have wrong syntax inside your first if. See my update.
The parentheses update did it! Somewhere in my customizing from my copy and paste I must have lost it. Embarrasingly obvious now that I see it. Thanks :)
0
 $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.

answered Sep 29, 2018 at 16:19

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.