Upgrading from 6.x to 7.x
Installation
If you are using composer then you should update the require section of your composer.json
file.
composer require league/csv:~7.0
This will edit (or create) your composer.json
file.
Added features
To improving writing speed you can now control data formatting and validation insertion prior to CSV addition:
Please refer to the documentation for more information.
Improved features
newline
The newline feature introduced during the 6.X series is completed by
- adding the setter and getter methods to the
Reader
class. - adding the
$newline
character as a second argument of thecreateFromString
named constructor. When set, the method internally use thesetNewline
method to make sure the property is correctly set for future use.
newReader and newWriter
All the CSV properties are now copied to the new instance when using both methods.
BOM
When using the __toString
or output
methods the input BOM if it exists is stripped from the output.
Backward Incompatible Changes
PHP ini settings
If you are on a Mac OS X Server, add the following lines before using the library to help PHP detect line ending in Mac OS X.
if (! ini_get("auto_detect_line_endings")) {
ini_set("auto_detect_line_endings", '1');
}
//the rest of the code continue here...
Null Handling
The null handling has been removed from the Writer
class. If your code relied on it you can use the new validation and formatting capabilities of the Writer
class and :
- the
League\Csv\Plugin\SkipNullValuesFormatter
class to skip cell using foundednull
values - the
League\Csv\Plugin\ForbiddenNullValuesValidator
class to validate the absence ornull
values
By default null
value cells are converted to empty string so the old behavior is preserved.
Example 1 : Null value validation
Old code:
use League\Csv\Writer;
$writer = Writer::createFromPath('/path/to/your/csv/file.csv');
$writer->insertOne(["foo", null, "bar"]); //will throw an RuntimeException
New code:
use League\Csv\Writer;
use League\Csv\Plugin\ForbiddenNullValuesValidator;
$validator = new ForbiddenNullValuesValidator();
$writer = Writer::createFromPath('/path/to/your/csv/file.csv');
$writer->addValidator($validator, 'null_as_exception');
$writer->insertOne(["foo", null, "bar"]); //will throw an League\Csv\Exception\InvalidRowException
Example 2 : Null value formatting
Old code:
use League\Csv\Writer;
$writer = Writer::createFromPath('/path/to/your/csv/file.csv');
$writer->setNullHandlingMode(Writer::NULL_AS_SKIP_CELL);
$writer->insertOne(["foo", null, "bar"]);
//the actual inserted row will be ["foo", "bar"]
New code:
use League\Csv\Writer;
use League\Csv\Plugin\SkipNullValuesFormatter;
$formatter = new SkipNullValuesFormatter();
$writer = Writer::createFromPath('/path/to/your/csv/file.csv');
$writer->addFormatter($formatter);
$writer->insertOne(["foo", null, "bar"]);
//the actual inserted row will be ["foo", "bar"]
Row consistency check
Directly checking row consistency has been removed from the Writer
class. If your code relied on it you can use the new validation and formatting capabilities of the Writer
class and:
- the
League\Csv\Plugin\ColumnConsistencyValidator
class.
Old code:
use League\Csv\Writer;
$writer = Writer::createFromPath('/path/to/your/csv/file.csv');
$writer->setNullHandlingMode(Writer::NULL_AS_EMPTY);
$writer->autodetectColumnsCount();
$writer->getColumnsCount(); //returns -1
$writer->insertOne(["foo", null, "bar"]);
$nb_column_count = $writer->getColumnsCount(); //returns 3
New code:
use League\Csv\Writer;
use League\Csv\Plugin\ColumnConsistencyValidator;
$validator = new ColumnConsistencyValidator();
$validator->autodetectColumnsCount();
$validator->getColumnsCount(); //returns -1
$writer = Writer::createFromPath('/path/to/your/csv/file.csv');
$writer->addValidator($validator, 'column_consistency');
$writer->insertOne(["foo", null, "bar"]);
$nb_column_count = $validator->getColumnsCount(); //returns 3
CSV conversion methods
jsonSerialize
, toXML
and toHTML
methods returns data is affected by the Reader
query options methods. You can directly narrow the CSV conversion into a json string, a DOMDocument
object or a HTML table if you filter your data prior to using the conversion method.
As with any other Reader
extract method, the query options are resetted after a call to the above methods.
Because prior to version 7.0 the conversion methods were not affected, you may have to update your code accordingly.
Old behavior:
use League\Csv\Reader;
$reader = Reader::createFromPath('/path/to/your/csv/file.csv', 'r');
$reader->setOffset(1);
$reader->setLimit(5);
$reader->toHTML(); //would convert the full CSV
New behavior:
use League\Csv\Reader;
$reader = Reader::createFromPath('/path/to/your/csv/file.csv', 'r');
$reader->setOffset(1);
$reader->setLimit(5);
$reader->toHTML(); //will only convert the 5 specified rows
Of course, since the query options methods do not exist on the Writer
class. The changed behavior does not affect the latter class.
CSV Instantiation
You can no longer use Reader
and Writer
default constructors. You are required to use the named constructors. This is done in order to clarify $open_mode
argument usage on instantiation. See below for a concrete example.
Removed behavior:
use League\Csv\Writer;
$file = '/path/to/my/file.csv';
$fileObject = new SplFileObject($file, 'r+');
$sol1 = new Writer($file, 'w');
$sol2 = new Writer($fileObject, 'w');
$sol1
open mode will bew
and newSplFileObject
object is created internally$sol2
open mode will ber+
and$fileObject
is directly used. The provided$open_mode
argument has no effect.
Supported behavior:
use League\Csv\Writer;
$file = '/path/to/my/file.csv';
$fileObject = new SplFileObject($file, 'r+');
$sol1 = Writer::createFromPath($file, 'w');
$sol2 = Writer::createFromFileObject($fileObject);
$sol3 = Writer::createFromPath($fileObject, 'w');
$sol1
open mode will bew
and newSplFileObject
object is created internally;$sol2
open mode will ber+
and$fileObject
is directly used;$sol3
was not possible using default constructor and is equivalent to$sol1
;
CSV properties
- The new default
SplFileObject
flags used areSplFileObject::READ_CSV
andSplFileObject::DROP_NEW_LINE
. TheSplFileObject::READ_CSV
is the only flag that can not be overridden by the developer to ensure consistency in methods usage. - CSV properties setter methods no longer provides default values. When used, you are require to provide a value to the method.
Detecting CSV Delimiters
Starting with version 7.0, each found delimiter index represents the character occurences in the specify CSV data.
use League\Csv\Reader;
$reader = Reader::createFromPath('/path/to/your/csv/file.csv', 'r');
$delimiters_list = $reader->detectDelimiterList(10, [' ', '|']);
foreach ($delimiters_list as $occurrences => $delimiter) {
echo "$delimiter appeared $occurrences times in 10 CSV row", PHP_EOL;
}
//$occurrences can not be less than 1
//since it would mean that the delimiter is not used
//if you are only interested in getting
// the most use delimiter you can still do as follow
if (count($delimiters_list)) {
$delimiter = array_shift($delimiters);
}
Reader::fetchColumn
Prior to version 7.0 when, if the column did not exist in the csv data the method returned an array full of null values.
Old behavior:
use League\Csv\Reader;
//this CSV contains only 2 column
$reader = Reader::createFromPath('/path/to/your/csv/file.csv', 'r');
$arr = $reader->fetchColumn(3);
//$arr is a array containing only null values;
New behavior:
use League\Csv\Reader;
//this CSV contains only 2 column
$reader = Reader::createFromPath('/path/to/your/csv/file.csv', 'r');
$arr = $reader->fetchColumn(3);
//$arr is empty
Row with non existing values are skipped from the result set.