LeagueCSV

Versions

RFC4180 Field compliance

This class is deprecated as of version 9.2.0. Please use the setEscape method directly with the empty escape character argument instead with the Reader or the Writer object.

The RFC4180Field class enables to work around the following bugs in PHP’s native CSV functions:

When using this stream filter you can easily create or read a RFC4180 compliant CSV document using League\Csv connections objects.

Changing the CSV objects control characters after registering the stream filter may result in unexpected returned records.

Usage with League\CSV objects

public static RFC4180Field::addTo(AbstractCsv $csv, string $whitespace_replace = ''): AbstractCsv

The RFC4180Field::addTo method will register the stream filter if it is not already the case and add the stream filter to the CSV object using the following properties:

use League\Csv\RFC4180Field;
use League\Csv\Writer;

$writer = Writer::createFromPath('php://temp', 'r+');
$writer->setNewline("\r\n"); //RFC4180 Line feed
RFC4180Field::addTo($writer); //adding the stream filter to fix field formatting
$writer->insertAll($iterable_data);
$writer->output('mycsvfile.csv'); //outputting a RFC4180 compliant CSV Document

the $whitespace_replace argument is available since version 9.1.0

When the $whitespace_replace sequence is different from the empty space and does not contain:

its value will be used to:

use League\Csv\RFC4180Field;
use League\Csv\Writer;

$writer = Writer::createFromPath('php://temp', 'r+');
RFC4180Field::addTo($writer, "\0");
$writer->insertOne(['foo bar', 'bar']);
echo $writer->getContent(); //display 'foo bar,bar' instead of '"foo bar",bar'

The $whitespace_replace sequence should be a sequence not present in the inserted records, otherwise your CSV content will be affected by it.

use League\Csv\RFC4180Field;
use League\Csv\Writer;

$writer = Writer::createFromPath('php://temp', 'r+');
RFC4180Field::addTo($writer, 'fo'); //incorrect sequence this will alter your CSV
$writer->insertOne(['foo bar', 'bar']);
echo $writer->getContent(); //display ' o bar,baz' instead of 'foo bar,baz'

On records insertion

To fully comply with RFC4180 you will also need to use League\Csv\Writer::setNewline.

On records extraction

Conversely, to read a RFC4180 compliant CSV document, when using the League\Csv\Reader object, you just need to add the League\Csv\RFC4180Field stream filter as shown below:

use League\Csv\Reader;
use League\Csv\RFC4180Field;

//the current CSV is ISO-8859-15 encoded with a ";" delimiter
$csv = Reader::createFromPath('/path/to/rfc4180-compliant.csv', 'r');
RFC4180Field::addTo($csv); //adding the stream filter to fix field formatting

foreach ($csv as $record) {
    //do something meaningful here...
}

Usage with PHP stream resources

public static RFC4180Field::register(): void
public static RFC4180Field::getFiltername(): string

To use this stream filter outside League\Csv objects you need to:

use League\Csv\RFC4180Field;

RFC4180Field::register();

$resource = fopen('/path/to/my/file', 'r');
$filter = stream_filter_append($resource, RFC4180Field::getFiltername(), STREAM_FILTER_READ, [
    'enclosure' => '"',
    'escape' => '\\',
    'mode' => STREAM_FILTER_READ,
]);

while (false !== ($record = fgetcsv($resource))) {
    //$record is correctly parsed
}