Search code examples
phpcsvfgetcsvline-endings

PHP fgetcsv and a custom line ending character


I am importing a csv using php and since the csv can sometimes be large I am doing so by streaming the file 4096 bytes at a time with the following code:

if(($handle = fopen($file, 'r')) !== false)
    {
        // loop through the file line-by-line
        while(($data = fgetcsv($handle)) !== false)
        {
            echo var_dump($data);
            unset($data);
        }
        fclose($handle);
    }
    else
    {
        echo "unable to open file $file <br>";
    }

Some of the csvs have a non-standard line ending character ';' and I need to be able to specify the line ending manually so that fgetcsv is correctly getting each line of the csv.

I have read other solutions that suggest using the ini setting:

ini_set("auto_detect_line_endings", true);

But that has not solved the issue I am getting here.

A previous solution to this problem was to get the entire file and modify all of the non-standard line endings and replace them with carriage return and line feeds. This solution is no longer valid as the size of csvs has increased.

What I do get in the var dump is all of the lines of the csv instead of a single line of the csv. Example line from CSV:

"col1,col2,col3,col4,col5;col1,col2,col3,col4,col5;col1,col2,col3,col4,col5;"

Solution

  • Since fgetcsv() does not have a facility to change the line ending, you may alternatively read the file with stream_get_line() up to the delimiter, and then parse the line with str_getcsv()

    // Given a delimiter...
    $delimiter = ";";
    
    if(($handle = fopen($file, 'r')) !== false) {
      // Read the line up to the delimiter
      while ($line = stream_get_line($handle, 4096, $delimiter)) {
        // Parse the CSV line into an array
        $data = str_getcsv($line);
        var_dump($data);
      }
      fclose($handle);
    }