Palmtree CSV
, (*1)
A CSV reader and writer for PHP., (*2)
The Reader class implements the Iterator interface, loading one line into memory at a time. This means large files can be parsed
without hitting any memory limits., (*3)
Requirements
Installation
Use composer to add the package to your dependencies:, (*4)
composer require palmtree/csv
Usage
Reading
Reading from a CSV File
$csv = new Reader('people.csv');
foreach($csv as $row) {
$name = $row['name'];
if (isset($row['age'])) {
echo "age is set!";
}
}
Normalize Data Types
A number of different normalizers can be used to convert data from strings into certain data types.
Below is contrived example using some of the currently bundled normalizers:, (*5)
$csv = new Reader('/path/to/products.csv');
$csv->addNormalizers([
// Convert to integer
'product_id' => new NumberNormalizer(),
// Keep data as string but trim it
'name' => new StringNormalizer(),
// Convert to float, rounded to 4 decimal places
'price' => NumberNormalizer::create()->scale(4),
// Convert to boolean true or false
'enabled' => new BooleanNormalizer(),
// Convert to an array of integers
'related_product_ids' => new ArrayNormalizer(new NumberNormalizer()),
// Custom conversion with a callback
'specials' => new CallableNormalizer(fn ($value) => json_decode($value)),
]);
If your CSV contains no headers pass false as the second argument to the constructor:, (*6)
$csv = new Reader('people.csv', false);
// Alternatively, call the setHasHeaders() method after instantiation:
//$csv->setHasHeaders(false);
If your CSV headers are not on the first row you may specify the (zero based) row offset:, (*7)
$csv = new Reader('people.csv');
// Headers are on the second row so let's set the offset to 1
$csv->setHeaderOffset(1);
Inline Reading
You may use the InlineReader to parse a CSV string rather than a file, if it was obtained from an API call or some other means:, (*8)
$csv = new \Palmtree\Csv\InlineReader('"header_1","header_2"' . "\r\n" . '"foo","bar"');
Writing
Build and Download a CSV File
$people = [];
$people[] = [
'name' => 'Alice',
'age' => '24',
'gender' => 'Female',
];
$people[] = [
'name' => 'Bob',
'age' => '28',
'gender' => 'Male',
];
Downloader::download('filename.csv', $people);
Writing to a CSV File
$people = [];
$people[] = [
'name' => 'Alice',
'age' => '24',
'gender' => 'Female',
];
$people[] = [
'name' => 'Bob',
'age' => '28',
'gender' => 'Male',
];
Writer::write('/path/to/output.csv', $people);
See the examples directory for more usage examples., (*9)
Advanced Usage
CSV Control
You can access the document object to change the CSV delimiter, enclosure and escape character:, (*10)
$csv = new Reader('/path/to/input.csv');
$csv->setDelimiter("\t");
$csv->setEnclosure('"');
$csv->setEscapeCharacter("\\");
Line Endings
CSVs default to \r\n line endings. Access the document object if you need to change this:, (*11)
$csv = new Writer('/path/to/output.csv');
$csv->getDocument()->setLineEnding("\n");
Fine-grained Control
The document object extends PHP's SplFileObject and inherits its methods:, (*12)
$csv = new Reader('/path/to/input.csv');
$csv->getDocument()->setFlags(\SplFileObject::DROP_NEW_LINE);
Configuration
If you're trying to read a CSV file in or generated by an old Mac computer you may need to include
the following snippet before creating a new Reader instance:, (*13)
if (!ini_get('auto_detect_line_endings')) {
ini_set('auto_detect_line_endings', '1');
}
This is because Macs used to use \r as a line separator. See here for more details., (*14)
License
Released under the MIT license, (*15)