PHP fgetcsv() Gotcha

I quite often find myself with the need to pull the data from a CSV file into a system. This might be to fill out essential data like postcodes or to update a site with new content. What system I happen to be using dictates how I pull in the CSV file, but writing a quick parser is quite easy in PHP via the use of the fgetcsv() function.

Unfortunately, when using this function it is quite easy to miss something quite important and creates a quite useless piece of code. Take the following example. It appears to be fine at first glance, but the output of the code is always to run once and stop.

$fh = fopen('awesome_csv_data.csv', "r");

while ($data = fgetcsv($fh, 0, ',') !== FALSE) {
	echo count($data); // == 1
	var_dump($data); // == true
}

fclose($fh);

What the $data variable is being set to in the above code is TRUE. This is because we are setting the value of $data to the result of the comparison of "fgetcsv($fh, 0, ',') !== FALSE". To prevent this order of precedence we simply wrap the return value of fgetcsv() and use this in the comparison.

The first example should be written like this; which produces the correct result.

$fh = fopen('awesome_csv_data.csv', "r");

while (($data = fgetcsv($fh, 0, ',')) !== FALSE) {
	echo count($data); // == the number of records found
	var_dump($data); // == the data
}

fclose($fh);

This is an important lesson to learn about the order of precedence in PHP and is worth checking for if you have code that doesn't quite work. After first encountering this gotcha it wasn't until I had spent 15 minutes checking the CSV file and the code within the while loop for errors before I spotted what I had done wrong.

Comments

Hi Philip, I just want to thank you for sharing this. It helped me a lot to find something that was missing from my code when following a CSV parsing tutorial. Thanks!
Permalink

Add new comment

The content of this field is kept private and will not be shown publicly.
CAPTCHA
1 + 1 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.