CSV data manipulation made easy in PHP.

composer require league/csv:^9.0

Once a new major version is released, the previous stable release remains supported for six more months with patches and security fixes.


The library was designed for developers who want to deal with CSV data using modern code and without the high levels of bootstrap and low-levels of usefulness provided by existing core functions or third-party code.

  1. Simple API

  2. Read and Write to CSV documents in a memory efficient and scalable way

  3. Support PHP Stream filtering capabilities

  4. Transform CSV documents into popular formats (JSON, XML or HTML)

  5. Framework-agnostic


Accessing CSV documents records

Reader, the read only connection object enables accessing CSV records easily

use League\Csv\Reader;

//load the CSV document from a file path
$csv = Reader::createFromPath('/path/to/your/csv/file.csv', 'r');

$header = $csv->getHeader(); //returns the CSV header record
$records = $csv->getRecords(); //returns all the CSV records as an Iterator object

echo $csv->toString(); //returns the CSV document as a string

Adding new CSV records is made simple

Writer, the write only connection object enables adding one or more records in one call.

use League\Csv\Writer;

$header = ['first name', 'last name', 'email'];
$records = [
    [1, 2, 3],
    ['foo', 'bar', 'baz'],
    ['john', 'doe', 'john.doe@example.com'],

//load the CSV document from a string
$csv = Writer::createFromString();

//insert the header

//insert all the records

echo $csv->toString(); //returns the CSV document as a string

Advanced CSV records selection

Statement, the constraint builder object ease CSV records selection

use League\Csv\Reader;
use League\Csv\Statement;

//load the CSV document from a stream
$stream = fopen('/path/to/your/csv/file.csv', 'r');
$csv = Reader::createFromStream($stream);

//build a statement
$stmt = Statement::create()

//query your records from the document
$records = $stmt->process($csv);
foreach ($records as $record) {
    //do something here

CSV documents converters

Different converters objects ease transforming your CSV documents into other popular formats

use League\Csv\Reader;
use League\Csv\XMLConverter;

//load the CSV document from a SplFileObject
$file = new SplFileObject('/path/to/your/csv/file.csv', 'r');
$csv = Reader::createFromFileObject($file);

$converter = XMLConverter::create()
    ->recordElement('record', 'offset')
    ->fieldElement('field', 'name');

$dom = $converter->convert($csv);
$dom->formatOutput = true;
$dom->encoding = 'iso-8859-15';

echo '<pre>', PHP_EOL;
echo htmlentities($dom->saveXML());
// <?xml version="1.0" encoding="iso-8859-15"?>
// <csv>
//   ...
//   <record offset="71">
//     <field name="prenoms">Anaïs</field>
//     <field name="nombre">137</field>
//     <field name="sexe">F</field>
//     <field name="annee">2004</field>
//   </record>
//   ...
//   <record offset="1099">
//     <field name="prenoms">Anaïs</field>
//     <field name="nombre">124</field>
//     <field name="sexe">F</field>
//     <field name="annee">2005</field>
//   </record>
// </csv>

Supports PHP Stream filter API

PHP stream filters can directly be used to ease manipulating CSV document

use League\Csv\Reader;

$csv = Reader::createFromPath('/path/to/your/csv/file.csv', 'r');

$input_bom = $csv->getInputBOM();

if ($input_bom === Reader::BOM_UTF16_LE || $input_bom === Reader::BOM_UTF16_BE) {

foreach ($csv as $record) {
    //all fields from the record are converted from UTF-16 into UTF-8 charset
    //and the BOM sequence is removed


CSV was created by Ignace Nyamagana Butera. Find him on Twitter at @nyamsprod.