PHP's fgetcsv returning false at beginning of file

2.5k views Asked by At

This is a PHP script running under Windows. It had been working but has recently stopped.

The file is opened and a valid file handle is returned: $fh = fopen($filename, 'r');

However, the very first time I call fgetcsv it returns false:

$headers = fgetcsv($fh, 6000, ',');
$line_no++;
if($headers === FALSE){
    echo 'Error parsing file headers';
}

This is now happening on all csv files I try. Other changes I have tried to no avail are:

  • ini_set('auto_detect_line_endings', true); Right before opening the file
  • rewind($fh); Right after opening the file
  • Using both 0 or a number like 6000 for the second parameter, length.
  • Changing the file's line endings style from unix to Windows and Mac

It seems like something with Windows is causing this file not to parse.

Is there any way to return the actual error from fgetcsv? The documentation doesn't say there is, just that it returns false on any error. Are there other Windows settings that could be causing issues? The Windows security settings give everyone full control of the files.

2

There are 2 answers

1
William W On BEST ANSWER

The issue turned out to be that a change at the beginning of the script was using the same file as a lock file so the script wouldn't be run on the same file twice at the same time. Then, later in the script when I actually wanted to parse the file, I opened it again (which was successful), but then I couldn't actually read the contents.

The solution I used was to create a temporary lock file based on the filename instead of using the actual file. Eg: $filename.'.lock'

It was a silly mistake on my part, however it would have been much more helpful if PHP had returned or written an error/warning at some point.

2
Kevin_Kinsey On

The canonical way to debug this would be "print_r($headers)".

As fgetcsv returns an array, it must be empty or a non-array. If you can configure (or have configured) PHP to log errors to a known location (Windows with IIS would be "syslog" and should show up in the Event Viewer), you should be able to figure out what's wrong.