### Manual Installation with Autoloader Source: https://csv.thephpleague.com/9.0/installation Include the bundled autoloader script for manual installations. Ensure the path to the library is correctly set. ```php use League\Csv\Reader; use League\Csv\Writer; require '/path/to/league/csv/autoload.php'; // Your script starts here // ... ``` -------------------------------- ### Install League\Csv with Composer Source: https://csv.thephpleague.com/9.0/installation Use Composer to install the latest stable version of League\Csv. ```bash composer require league/csv:^9.28.0 ``` -------------------------------- ### Force Enclosure Example Source: https://csv.thephpleague.com/9.0/writer Demonstrates how to use `encloseAll` and `forceEnclosure` to ensure all records are enclosed. This example shows the output when all cells are enclosed. ```php encloseAll(); //return false; $writer->forceEnclosure(); $writer->encloseAll(); //return true; $writer->insertAll($collection); echo $writer->toString(), PHP_EOL; // the CSV file will contain enclosed cell. // Double quote are not added in presence of the // escape character as per PHP's CSV writing documentation // "1","2" // "value 2-0","value 2-1" // "to""to","foo\"bar" ``` -------------------------------- ### CSV Data Example Source: https://csv.thephpleague.com/9.0/reader/record-mapping This is an example of the CSV data structure used throughout the documentation for demonstrating record-to-object conversion. ```csv date,temperature,place 2011-01-01,,Abidjan 2011-01-02,24,Abidjan 2011-01-03,17,Abidjan 2011-01-01,18,Yamoussoukro 2011-01-02,23,Yamoussoukro 2011-01-03,21,Yamoussoukro ``` -------------------------------- ### Example String Values for Array Shapes Source: https://csv.thephpleague.com/9.0/reader/record-mapping Illustrates the expected string formats for 'list', 'csv', and 'json' shapes when casting to an array. ```php $array['list'] = "1,2,3,4"; //the string contains only a delimiter (shape list) $array['csv'] = '"1","2","3","4"'; //the string contains delimiter and enclosure (shape csv) $array['json'] = '{"foo":"bar"}'; //the string is a json string (shape json) ``` -------------------------------- ### Create and Process a Statement Source: https://csv.thephpleague.com/9.0/reader/statement Instantiate a Statement object using the create method and process it with a CSV Reader instance. This example retrieves all records from the CSV file. ```php use League\Csv\Reader; use League\Csv\Statement; $reader = Reader::from('/path/to/file.csv'); $records = (new Statement())->process($reader); // $records is a League\Csv\ResultSet instance ``` -------------------------------- ### Using league/csv with Doctrine Criteria (v9.16.0+) Source: https://csv.thephpleague.com/9.0/extensions/doctrine This example demonstrates how to use the integrated Criteria API in league/csv v9.16.0 and later, which replaces the need for the separate league/csv-doctrine package. ```php setHeaderOffset(0); $csv->setDelimiter(';'); $criteria = (new Statement()) ->andWhere('prenom', '=', 'Adam') ->orderByAsc('annee') ->orderByDesc('foo') ->offset(3) ->limit(10); $resultset = $criteria->process($csv); ``` -------------------------------- ### Comparing Two Columns with Statement Methods Source: https://csv.thephpleague.com/9.0/reader/statement Shows how to compare two columns using `andWhereColumn` and `whereNotColumn`. The `whereNotColumn` example filters based on the second column specified by its integer offset. ```php use League\Csv\Reader; use League\Csv\Statement; $reader = Reader::from('/path/to/file.csv'); $records = (new Statement()) ->andWhereColumn('created_at', '<', 'update_at') //filtering is done on both column value ->whereNotColumn('fullname', 'starts_with', 4) //filtering is done on both column but the second column is specified via its offset ->process($reader); ``` -------------------------------- ### Including Input BOM in CSV Output Source: https://csv.thephpleague.com/9.0/connections/bom This example demonstrates how to include the input BOM in the CSV output. It sets up a CSV reader from a string, explicitly includes the input BOM, and then outputs the CSV content, resulting in two BOM markers in the final document. ```php $raw_csv = Bom::Utf8->value."john,doe,john.doe@example.com\njane,doe,jane.doe@example.com\n"; $csv = Reader::fromString($raw_csv); $csv->setOutputBOM(Bom::Utf16Le); $csv->includeInputBOM(); ob_start(); $csv->output(); $document = ob_get_clean(); ``` -------------------------------- ### Download CSV as JSON with General Headers Source: https://csv.thephpleague.com/9.0/converter/json Downloads CSV data as a JSON file directly to the browser. This example includes common caching and content headers for file downloads. ```php use League\Csv\Reader; use League\Csv\JsonConverter; $reader = Reader::from('file.csv'); $reader->setHeaderOffset(0); header('Cache-Control: no-cache, no-store, must-revalidate'); header('Pragma: no-cache'); header('Expires: 0'); header('Content-Type: application/json; charset=UTF-8'); header('Content-Description: File Transfer'); header('Content-Disposition: attachment; filename="name-for-your-file.json"'); (new JsonConverter())->download($reader); die; ``` -------------------------------- ### Custom Query Constraints with Criteria and Closures Source: https://csv.thephpleague.com/9.0/reader/statement Demonstrates creating custom filtering logic using `League\Csv\Query\Constraint\Criteria` and closures. This example filters an array of records based on 'volume' greater than 80 and 'edition' less than 6, combined with an XOR logical operator. ```php use League\Csv\Query; $data = [ ['volume' => 67, 'edition' => 2], ['volume' => 86, 'edition' => 1], ['volume' => 85, 'edition' => 6], ['volume' => 98, 'edition' => 2], ['volume' => 86, 'edition' => 6], ['volume' => 67, 'edition' => 7], ]; $criteria = Query\Constraint\Criteria::xany( Query\Constraint\Column::filterOn('volume', 'gt', 80), fn (mixed $record, int|string $key) => Query\Row::from($record)->field('edition') < 6 ); $filteredData = array_filter($data, $criteria, ARRAY_FILTER_USE_BOTH)); //Filtering an array using the XOR logical operator ``` -------------------------------- ### Detect BOM from a character sequence Source: https://csv.thephpleague.com/9.0/connections/bom Use `Bom::tryFromSequence` to detect a BOM sequence at the start of a string. It returns a Bom instance or null if no BOM is found. `Bom::fromSequence` throws a ValueError instead of returning null. ```PHP use League\Csv\Bom; Bom::tryFromSequence('hello world!'); //returns null Bom::tryFromSequence(Bom::Utf8->value.'hello world!'); //returns Bom::Utf8 Bom::tryFromSequence('hello world!'.Bom::Utf16Le->value); //returns null ``` -------------------------------- ### Set CSV Escape Character to Empty String Source: https://csv.thephpleague.com/9.0/connections/controls Starting with PHP 7.4, setting the escape character to an empty string is recommended for better RFC4180 compliance. This example demonstrates setting and retrieving an empty escape character. ```PHP use League\Csv\Reader; $csv = Reader::from('/path/to/file.csv', 'r'); $csv->setEscape(''); $escape = $csv->getEscape(); //returns "" ``` -------------------------------- ### Instantiating and Checking Buffer State Source: https://csv.thephpleague.com/9.0/writer/buffer Demonstrates how to create a Buffer from a Reader slice and check its initial state, including emptiness, header presence, and record offsets. Also shows creating an empty buffer and checking its state. ```php use League\Csv\Buffer; use League\Csv\Reader; use League\Csv\Statement; $reader = Reader::from('/path/to/file.csv'); $reader->setHeaderOffset(0); $buffer = Buffer::from($reader->slice(50, 30000))); $buffer->isEmpty(); // returns false $buffer->hasHeader(); // returns true $buffer->firstOffset(); // returns 50 $buffer->lastOffset(); // returns the offset of the last inserted record $buffer->recordCount(); // the total number of rows in the instance $emptyBuffer = new Buffer(); $emptyBuffer->isEmpty(); // returns true $emptyBuffer->hasHeader(); // returns false $emptyBuffer->firstOffset(); // returns null $emptyBuffer->lastOffset(); // returns null $emptyBuffer->recordCount(); // returns 0 ``` -------------------------------- ### Filtering Records with Operators (andWhere, orWhere, whereNot) Source: https://csv.thephpleague.com/9.0/reader/statement Filter records using predefined operators for column values. This example selects records where the 2nd cell is '10', or the 'birthdate' column matches a regex, and excludes those where 'firstname' starts with 'P'. ```PHP use League\Csv\Reader; use League\Csv\Statement; $reader = Reader::from('/path/to/file.csv'); $records = (new Statement()) ->andWhere(1, '=', '10') //filtering is done of the second column ->orWhere('birthdate', 'regexp', '/\d{1,2}\/\d{1,2}\/\d{2,4}/') //filtering is done on the `birthdate` column ->whereNot('firstname', 'starts_with', 'P') //filtering is done case-sensitively on the first character of the column value ->process($reader); // $records is a League\Csv\ResultSet instance ``` -------------------------------- ### Inserting Records into an Empty Buffer Source: https://csv.thephpleague.com/9.0/writer/buffer Demonstrates inserting records into a new Buffer instance using both array lists and associative arrays. Shows how the header is initially empty and how records are stored. ```php $buffer = new Buffer(); $buffer->getHeader(); // returns [] $buffer->hasHeader(); // return false $buffer->insert( ['moko', 'mibalé', 'misató'], [ 'first column' => 'un', 'second column' => 'deux', 'third column' => 'trois', ], ['one', 'two', 'three'], ); // returns 3 return iterator_to_array($buffer->getRecords()); // [ // ['moko', 'mibalé', 'misató'], // ['un', 'deux', 'trois'], // ['one', 'two', 'three'], // ]; ``` -------------------------------- ### Buffer State and Inspection Methods Source: https://csv.thephpleague.com/9.0/writer/buffer This snippet demonstrates how to instantiate a Buffer, load data from a CSV reader, and inspect its state using methods like isEmpty, hasHeader, firstOffset, lastOffset, and recordCount. ```APIDOC ## Buffer State and Inspection ### Description This section details the methods available on the `Buffer` class to inspect its current state, such as checking if it's empty, if it has a header, and retrieving the first and last record offsets. ### Methods - **`Buffer::hasHeader()`** - **Description**: Checks whether a non-empty header is attached to the buffer. - **Returns**: `bool` - **`Buffer::isEmpty()`** - **Description**: Checks whether the instance contains any records. - **Returns**: `bool` - **`Buffer::firstOffset()`** - **Description**: Returns the first offset in the buffer. - **Returns**: `int|null` - The first offset or `null` if the instance is empty. - **`Buffer::lastOffset()`** - **Description**: Returns the last offset in the buffer. - **Returns**: `int|null` - The last offset or `null` if the instance is empty. - **`Buffer::recordCount()`** - **Description**: Returns the total number of records currently present in the instance. - **Returns**: `int` ### Example ```php use League\Csv\Buffer; use League\Csv\Reader; // Assuming $reader is a configured League\Csv\Reader instance // $reader = Reader::from('/path/to/file.csv'); // $reader->setHeaderOffset(0); // Example with data loaded from a reader // $buffer = Buffer::from($reader->slice(50, 30000)); // echo $buffer->isEmpty(); // Output: false (if records exist) // echo $buffer->hasHeader(); // Output: true (if header is set) // echo $buffer->firstOffset(); // Output: 50 (or the first offset) // echo $buffer->lastOffset(); // Output: Offset of the last inserted record // echo $buffer->recordCount(); // Output: Total number of rows // Example with an empty buffer $emptyBuffer = new Buffer(); // echo $emptyBuffer->isEmpty(); // Output: true // echo $emptyBuffer->hasHeader(); // Output: false // echo $emptyBuffer->firstOffset(); // Output: null // echo $emptyBuffer->lastOffset(); // Output: null // echo $emptyBuffer->recordCount(); // Output: 0 ``` ``` -------------------------------- ### Inserting Records with Header (List) Source: https://csv.thephpleague.com/9.0/writer/buffer Shows how to insert a record as a list into a Buffer that has a header, provided the list length matches the header length. Demonstrates retrieving the last inserted record. ```php $affectedRowsCount = $buffer->insert(['first', 'second', 'third']); $buffer->last(); // returns ['column1' => 'first', 'column2' => 'second', 'column3' => 'third']; ``` -------------------------------- ### Get CSV Content as String Source: https://csv.thephpleague.com/9.0/connections/output Use the `toString` method to get the full CSV content as a string. This method is recommended over the deprecated `getContent` and `__toString` methods. ```PHP use League\Csv\Reader; $reader = Reader::from('/path/to/my/file.csv', 'r'); echo $reader->toString(); ``` -------------------------------- ### Importing Header from Reader Source: https://csv.thephpleague.com/9.0/writer/buffer Illustrates creating a Buffer instance from a Reader object, which automatically imports the header if set on the Reader. Shows how to access the imported header. ```php $document = Reader::from('path/to/file.csv'); $document->setHeaderOffset(0); //the Reader header will be imported alongside its records $buffer = Buffer::from($document); $buffer->getHeader(); // returns ['column1', 'column2', 'column3'] $buffer->hasHeader(); // return true ``` -------------------------------- ### Get List of Registered Filter Names Source: https://csv.thephpleague.com/9.0/connections/filters Retrieves a list of all filter names that have been registered with the CallbackStreamFilter class. ```php CallbackStreamFilter::registeredFilterNames(); // returns a list ``` -------------------------------- ### Deprecated AfterMapping Attribute Source: https://csv.thephpleague.com/9.0/reader/record-mapping The AfterMapping attribute is deprecated and replaced by MapRecord. If both are used, AfterMapping content is ignored. This example is for reference. ```php use League\Csv\Serializer; #[Serializer\AfterMapping('validate')] final class ClimateRecord { public function __construct( public readonly Place $place, public readonly ?float $temperature, public readonly ?DateTimeImmutable $date, ) { $this->validate(); } protected function validate(): void { //further validation on your object //or any other post construction methods //that is needed to be called } } ``` -------------------------------- ### Create CSV Reader and Fetch Rows Source: https://csv.thephpleague.com/reading Initializes a CSV reader from a file path in read mode and iterates through fetched rows. Ensure the file exists and is readable. ```php use League\Csv\Reader; $reader = Reader::createFromPath('/path/to/my/file.csv', 'r'); $results = $reader->fetch(); foreach ($results as $row) { //do something here } ``` -------------------------------- ### Get CSV Records as Arrays Source: https://csv.thephpleague.com/9.0/reader Use the `getRecords` method to iterate over all CSV records as arrays. This method is part of the `TabularDataReader` API. ```php use League\Csv\Reader; $reader = Reader::from('/path/to/my/file.csv', 'r'); $records = $reader->getRecords(); foreach ($records as $offset => $record) { //$offset : represents the record offset //var_export($record) returns something like // array( // 'john', // 'doe', // 'john.doe@example.com' // ); } ``` -------------------------------- ### Get Pathname from CSV Reader Source: https://csv.thephpleague.com/9.0/connections/instantiation Retrieves the pathname of the underlying document for a CSV Reader instance. This feature is available from version 9.2.0. ```php use League\Csv\Reader; Reader::from(new SplFileObject('/path/to/your/csv/file.csv'))->getPathname(); //returns '/path/to/your/csv/file.csv' ``` -------------------------------- ### Reader Class: FetchAssoc with Query Filters (Before) Source: https://csv.thephpleague.com/9.0/upgrading Illustrates using fetchAssoc with query filters (limit, offset) applied directly to the Reader object. ```php use League\Csv\Reader; $reader = Reader::createFromPath('/path/to/file.csv', 'r'); $records = $reader ->limit(5) ->offset(3) ->fetchAssoc(['firstname', 'lastname', 'email']) ; ``` -------------------------------- ### Accessing First and Last Records Source: https://csv.thephpleague.com/9.0/writer/buffer This snippet shows how to retrieve the first and last records from a Buffer instance, including methods to get them as objects. ```APIDOC ## Accessing First and Last Records ### Description This section covers the methods for accessing the first and last records stored within the `Buffer`. It also includes methods to retrieve these records mapped as objects. ### Methods - **`Buffer::first()`** - **Description**: Returns the first inserted record as an array. - **Returns**: `array` - The first record or an empty array if no records are present. - **`Buffer::firstAsObject(string $objectType)`** - **Description**: Returns the first inserted record mapped to the specified object type. - **Parameters**: - **`$objectType`** (string) - The fully qualified class name of the object to map the record to. - **Returns**: `object|null` - An instance of the specified object type on success, or `null` if no records are present or mapping fails. - **`Buffer::last()`** - **Description**: Returns the last inserted record as an array. - **Returns**: `array` - The last record or an empty array if no records are present. - **`Buffer::lastAsObject(string $objectType)`** - **Description**: Returns the last inserted record mapped to the specified object type. - **Parameters**: - **`$objectType`** (string) - The fully qualified class name of the object to map the record to. - **Returns**: `object|null` - An instance of the specified object type on success, or `null` if no records are present or mapping fails. ### Example ```php use League\Csv\Buffer; // Assuming $buffer is a populated Buffer instance // $buffer = Buffer::from($reader->slice(50, 30000)); // $firstRecord = $buffer->first(); // Example output: ['firstname' => 'john', 'lastname' => 'doe', 'email' => 'johh.doe@example.com'] // $firstUser = $buffer->firstAsObject(User::class); // Assuming User class exists // Returns a User instance on success, or null // $emptyBuffer = new Buffer(); // $lastRecord = $emptyBuffer->last(); // Returns [] // $lastUser = $emptyBuffer->lastAsObject(User::class); // Returns null ``` ``` -------------------------------- ### Iterating over Reader with foreach Source: https://csv.thephpleague.com/9.0/upgrading Before version 9.0, `Reader::fetchAll()` was used to get all records. Now, `Reader` implements `IteratorAggregate`, allowing direct iteration with `foreach`. ```php use League\Csv\Reader; $reader = Reader::createFromPath('/path/to/file.csv', 'r'); foreach ($reader->fetchAll() as $key => $value) { // do something here } ``` ```php use League\Csv\Reader; $reader = Reader::createFromPath('/path/to/file.csv', 'r'); foreach ($reader as $record) { // do something here } ``` -------------------------------- ### Order Records using orderByDesc and orderByAsc Source: https://csv.thephpleague.com/9.0/reader/statement Demonstrates simpler ordering methods `orderByDesc` and `orderByAsc` for sorting by column index or name. An optional callback can be provided for custom sorting logic. Requires `League Csv Reader` and `League Csv Statement`. ```php use League Csv Reader; use League Csv Statement; $reader = Reader::from('/path/to/file.csv'); $records = (new Statement()) ->orderByDesc(1) //descending order according to the data of the 2nd column ->orderByAsc('foo', strcmp(...)) //ascending order according a callback compare function ->process($reader); // $records is a League Csv ResultSet instance ``` -------------------------------- ### Instantiating JsonConverter Source: https://csv.thephpleague.com/9.0/converter/json Demonstrates the instantiation of the JsonConverter class. The `create` named constructor is deprecated in favor of direct constructor calls. ```PHP (new JsonConverter())->download($record); ``` ```PHP new JsonConverter()->download($record); ``` -------------------------------- ### Filtering Records with a Callable Source: https://csv.thephpleague.com/9.0/reader/statement Use the `where` method with a callable to filter records based on custom logic. This example removes records where the 3rd field is not a valid email. ```PHP use League\Csv\Reader; use League\Csv\Statement; $reader = Reader::from('/path/to/file.csv'); $records = (new Statement()) ->where(fn (array $record): bool => false !== filter_var($record[2] ?? '', FILTER_VALIDATE_EMAIL)) ->process($reader); // $records is a League\Csv\ResultSet instance ``` -------------------------------- ### Inserting Records with Header (Associative Array) Source: https://csv.thephpleague.com/9.0/writer/buffer Demonstrates inserting a record as an associative array into a Buffer with a header, where the keys must match the header values. ```php $affectedRowsCount = $buffer->insert([ 'column1' => 'first', 'column2' => 'second', 'column3' => 'third', ]); ``` -------------------------------- ### Add Formatter to Writer Source: https://csv.thephpleague.com/9.0/writer Example of adding a record formatter to a Writer object. This formatter converts all values in a record to uppercase. Formatters are applied in FIFO order. ```php use League\Csv\Writer; $formatter = function (array $row): array { return array_map('strtoupper', $row); }; $writer = Writer::from(new SplTempFileObject()); $writer->addFormatter($formatter); $writer->insertOne(['john', 'doe', 'john.doe@example.com']); echo $writer->toString(); //will display JOHN,DOE,JOHN.DOE@EXAMPLE.COM ``` -------------------------------- ### Managing Registered Types and Aliases Source: https://csv.thephpleague.com/9.0/reader/record-mapping Demonstrates methods for unregistering specific types, all types, and listing currently registered types. ```php use League\Csv\Serializer; Serializer\Denormalizer::unregisterType(Naira::class); Serializer\Denormalizer::unregisterAllTypes(); Serializer\Denormalizer::types(); ``` -------------------------------- ### Trimming Whitespace Before Casting Array Elements Source: https://csv.thephpleague.com/9.0/reader/record-mapping Enables trimming whitespace from array elements before casting when using 'list' or 'csv' shapes, starting from version 9.17.0. ```php use League\Csv\Serializer; #[Serializer\MapCell(options: ['trimElementValueBeforeCasting' => true])] public function setData(array $data): void; //with the following input $stringWithSpace = 'foo , bar, baz '; //will be converted to if you specify it ['foo', 'bar', 'baz'] // by default if you do not specify the new attribute the conversion will be ['foo ', ' bar', ' baz '] ``` -------------------------------- ### Using Type Alias with MapCell Attribute Source: https://csv.thephpleague.com/9.0/reader/record-mapping Example of using a registered type alias ('@forty_two') with the MapCell attribute to specify a custom casting method for an integer property. ```php use App\Domain\Money use League\Csv\Serializer; #[Serializer\MapCell(column: 'amount', cast: '@forty_two')] private ?int $amount; ``` -------------------------------- ### Using SwapDelimiter with CSV Writer Source: https://csv.thephpleague.com/9.0/interoperability/swap-delimiter Demonstrates how to use the SwapDelimiter stream filter with a CSV Writer object to write data using a multibyte delimiter. ```php use League\Csv\SwapDelimiter; use League\Csv\Writer; $writer = Writer::fromString(); $writer->setDelimiter("\x02"); SwapDelimiter::addTo($writer, '💩'); $writer->insertOne(['toto', 'tata', 'foobar']); $writer->toString(); //returns toto💩tata💩foobar\n ``` -------------------------------- ### Setting End of Line Sequence Source: https://csv.thephpleague.com/9.0/writer Illustrates how to set and get the end-of-line sequence for the CSV writer. The default is '\n', but it can be changed to sequences like '\r\n' for better interoperability. ```PHP use League\Csv\Writer; $writer = Writer::from(new SplFileObject()); $writer->getEndOfLine(); //returns "\n"; $writer->setEndOfLine("\r\n"); $writer->getEndOfLine(); //returns "\r\n"; $writer->insertOne(["one", "two"]); echo $writer->toString(); //displays "one,two\r\n"; ``` -------------------------------- ### Static Denormalization Methods Source: https://csv.thephpleague.com/9.0/reader/record-mapping Use static methods Denormalizer::assign and Denormalizer::assignAll for one-off denormalization tasks, where array keys are automatically used as property names. ```php setHeaderOffset(0); header('Cache-Control: no-cache, no-store, must-revalidate'); header('Pragma: no-cache'); header('Expires: 0'); //the filename will be the name of the downloaded xml as shown by your HTTP client! new XMLConverter()->download($reader, 'name-for-your-file.xml'); die; ``` -------------------------------- ### Load CSV Reader using from() with Path Source: https://csv.thephpleague.com/9.0/connections/instantiation Creates a new CSV Reader object from a file path, mode, and context. The mode defaults to 'r'. ```PHP use League\Csv\Reader; use League\Csv\Writer; $reader = Reader::from('/path/to/your/csv/file.csv', 'r'); ``` -------------------------------- ### Writer Class: Reduced Method Chaining (Before) Source: https://csv.thephpleague.com/9.0/upgrading Illustrates the previous ability to chain insertOne and insertAll methods on the Writer class. ```php use League\Csv\Writer; $writer = Writer::createFromFileObject(new SplTempFileObject()); $record = ['john', 'doe', 'john.doe@example.com']; $writer ->insertOne($record) ->insertAll([$record]) ->insertOne($record) ; ``` -------------------------------- ### Extracting Key-Value Pairs with fetchPairsWithoutDuplicates Source: https://csv.thephpleague.com/reading Use fetchPairsWithoutDuplicates to get an associative array of key-value pairs. This method overwrites entries if duplicate values are found in the specified value column. ```php $str = <<fetchPairsWithoutDuplicates(1, 0); // will return ['doe' => 'jane', 'foo' => 'bar']; // the 'john' value has been overwritten by 'jane' ``` -------------------------------- ### Download XML with Custom Encoding and Formatting Source: https://csv.thephpleague.com/9.0/converter/xml Downloads the generated XML with custom encoding (e.g., 'iso-8859-1') and enables XML output formatting. No validation is performed on the provided encoding string. ```php use League\Csv\Reader; use League\Csv\XMLConverter; $reader = Reader::from('file.csv'); $reader->setHeaderOffset(0); header('Cache-Control: no-cache, no-store, must-revalidate'); header('Pragma: no-cache'); header('Expires: 0'); new XMLConverter()->download( records: $reader, filename: 'generated_file.xml', encoding: 'iso-8859-1', formatOutput: true, ); die; ``` -------------------------------- ### Get CSV Records with Explicit Header Source: https://csv.thephpleague.com/9.0/reader Provide an explicit header array to `getRecords` which takes precedence over the header offset. The corresponding record will still be removed from the returned Iterator. ```php use League\Csv\Reader; $reader = Reader::from('/path/to/my/file.csv', 'r'); $reader->setHeaderOffset(0); $records = $reader->getRecords(['firstname', 'lastname', 'email']); foreach ($records as $offset => $record) { //$offset : represents the record offset //var_export($record) returns something like // array( // 'firstname' => 'jane', // 'lastname' => 'doe', // 'email' => 'jane.doe@example.com' // ); }//the first record will still be skipped!! ``` -------------------------------- ### Creating New Instances from CSV Objects Source: https://csv.thephpleague.com/upgrading/6.0 The `getReader` and `getWriter` methods have been removed. Use the new `newWriter` and `newReader` methods available on both `Reader` and `Writer` classes to create new instances. ```php use League\Csv\Reader; $reader = new Reader('/path/to/your/csv/file.csv'); $writer = $reader->getWriter('a+'); $another_reader = $writer->getReader(); ``` ```php use League\Csv\Reader; $reader = Reader::createFromPath('/path/to/your/csv/file.csv', 'r'); $writer = $reader->newWriter('a+'); $another_writer = $writer->newWriter('rb+'); $another_reader1 = $writer->newReader(); $another_reader2 = $reader->newReader(); ``` -------------------------------- ### Get Pathname from CSV Writer Source: https://csv.thephpleague.com/9.0/connections/instantiation Retrieves the pathname of the underlying document for a CSV Writer instance. For temporary streams, it returns 'php://temp'. This feature is available from version 9.2.0. ```php use League\Csv\Writer; Writer::from(new SplTempFileObject())->getPathname(); //returns php://temp ``` -------------------------------- ### Select Records with matching, matchingFirst, matchingFirstOrFail Source: https://csv.thephpleague.com/9.0/reader/tabular-data-reader Use these methods to select records based on RFC7111 expressions. `matching` returns all matches, `matchingFirst` returns the first match, and `matchingFirstOrFail` returns the first match or throws an exception if no match is found. ```php use League\Csv\Reader; $reader = Reader::fromString($csv); $reader->matching('row=3-1;4-6'); //returns an iterable containing all the TabularDataReader instance that are valid. $reader->matchingFirst('row=3-1;4-6'); // will return 1 selected fragment as a TabularReaderData instance $reader->matchingFirstOrFail('row=3-1;4-6'); // will throw ``` -------------------------------- ### Custom TypeCasting Interface Implementation Source: https://csv.thephpleague.com/9.0/reader/record-mapping Example implementation of the `TypeCasting` interface for custom data conversion. This class handles the conversion of cell values to a `Naira` object and supports default options. ```php */ final class CastToNaira implements TypeCasting { public function __construct( ReflectionProperty|ReflectionParameter $reflectionProperty, //always given by the Denormalizer ) { // It is recommended to handle the $reflectionProperty argument. // The argument gives you access to property/argument information. // it allows validating that the argument does support your casting // it allows adding support to union, intersection or unnamed type // it tells whether the property/argument is nullable or not. // in case of error you should throw a MappingFailed exception } public function setOptions( mixed ...$options //will be filled via the MapCell options array destructuring ): void { // in case of error you should throw a MappingFailed exception } public function toVariable(mixed $value): ?Naira { //convert the Cell value into the expected type // in case of error you should throw a TypeCastingFailed exception } } ``` -------------------------------- ### Callback Signature for Type Casting Source: https://csv.thephpleague.com/9.0/reader/record-mapping Illustrates the expected signature for callbacks used in type registration. It includes the value, nullability, and any additional options. ```php Closure(?string $value, bool $isNullable, ...$options): mixed; ``` -------------------------------- ### Inserting Records into the Buffer Source: https://csv.thephpleague.com/9.0/writer/buffer This section details how to insert records into a Buffer instance, supporting both array and associative array formats, with and without a header. ```APIDOC ## Inserting Records ### Description This section explains how to add records to a `Buffer` instance using the `insert` method. It covers inserting records as lists of values or as associative arrays, and details behavior with and without a defined header. ### Methods - **`Buffer::insert(array ...$records)`** - **Description**: Inserts one or more records into the buffer. Records can be provided as variadic arguments, each being either a list of values or an associative array. - **Parameters**: - **`...$records`** (array) - One or more records to insert. Each record can be an indexed array (list) or an associative array. - **Returns**: `int` - The number of successfully inserted records. - **Throws**: An exception if the insertion cannot occur (e.g., due to header mismatch or incorrect record structure). ### Behavior with Header - **With Header**: If the buffer has a header, inserted records must either match the header keys (for associative arrays) or have the same number of elements as the header (for indexed arrays). Inserting incomplete or mismatched records will result in an exception. - **Without Header**: If the buffer has no header, column consistency is not checked. Indexed arrays are inserted as is, and associative arrays are inserted without their keys being considered for column mapping. ### Example ```php use League\Csv\Buffer; use League\Csv\Reader; // Example 1: Inserting records into a buffer without a header $buffer = new Buffer(); $insertedCount = $buffer->insert( ['moko', 'mibalé', 'misató'], [ 'first column' => 'un', 'second column' => 'deux', 'third column' => 'trois', ], ['one', 'two', 'three'] ); // $insertedCount will be 3 // To view records: iterator_to_array($buffer->getRecords()) // Example 2: Inserting into a buffer with a header imported from a Reader // $document = Reader::from('path/to/file.csv'); // $document->setHeaderOffset(0); // $buffer = Buffer::from($document); // $buffer->getHeader(); // returns ['column1', 'column2', 'column3'] // Inserting with a list (must match header count) $buffer->insert(['first', 'second', 'third']); // $buffer->last(); // returns ['column1' => 'first', 'column2' => 'second', 'column3' => 'third'] // Inserting with an associative array (keys must match header names) $buffer->insert([ 'column1' => 'first', 'column2' => 'second', 'column3' => 'third', ]); // Example of an insertion that will trigger an exception: // $buffer->insert(['column1' => 'first', 'column3' => 'third']); // Incomplete associative array // $buffer->insert(['first', 'third']); // Incomplete list ``` ``` -------------------------------- ### Set and Get CSV Delimiter Source: https://csv.thephpleague.com/9.0/connections/controls Use `setDelimiter` to specify the delimiter character (e.g., ';') and `getDelimiter` to retrieve it. The delimiter must be a single byte character. Throws an exception if the length is not 1. ```PHP use League\Csv\Reader; $csv = Reader::from('/path/to/file.csv', 'r'); $csv->setDelimiter(';'); $delimiter = $csv->getDelimiter(); //returns ";" ``` -------------------------------- ### Writer Class: Reduced Method Chaining (After) Source: https://csv.thephpleague.com/9.0/upgrading Demonstrates the removal of method chaining for insertOne and insertAll in the Writer class; calls must be made sequentially. ```php use League\Csv\Writer; $writer = Writer::createFromFileObject(new SplTempFileObject()); $record = ['john', 'doe', 'john.doe@example.com']; $writer->insertOne($record); $writer->insertAll([$record]); $writer->insertOne($record); ``` -------------------------------- ### Limit and Offset Records Source: https://csv.thephpleague.com/9.0/reader/statement Limits the number of records returned to a maximum of 5, starting from the 10th record (offset 9). Requires `League Csv Reader` and `League Csv Statement`. ```php use League Csv Reader; use League Csv Statement; $reader = Reader::from('/path/to/file.csv'); $records = (new Statement()) ->limit(5) ->offset(9) ->process($reader); // $records is a League Csv ResultSet instance ``` -------------------------------- ### Download CSV as JSON with Specified Filename Source: https://csv.thephpleague.com/9.0/converter/json Downloads CSV data as a JSON file, simplifying header management by specifying the desired filename directly. Caching headers are optional and provided as an example. ```php use League\Csv\Reader; use League\Csv\JsonConverter; $reader = Reader::from('file.csv'); $reader->setHeaderOffset(0); header('Cache-Control: no-cache, no-store, must-revalidate'); header('Pragma: no-cache'); header('Expires: 0'); //the filename will be the name of the downloaded json as shown by your HTTP client! (new JsonConverter())->download($reader, 'generated_file.json'); die; ``` -------------------------------- ### Load CSV Writer using from() with Path Source: https://csv.thephpleague.com/9.0/connections/instantiation Creates a new CSV Writer object from a file path, mode, and context. The mode defaults to 'r+'. ```PHP use League\Csv\Reader; use League\Csv\Writer; $writer = Writer::from('/path/to/your/csv/file.csv', 'w'); ``` -------------------------------- ### Counting and Iterating CSV Records Source: https://csv.thephpleague.com/9.0/reader/tabular-data-reader Shows how to get the total number of records in a CSV file and iterate over each record using a foreach loop. This is fundamental for processing CSV data row by row. ```php use League\Csv\Reader; $reader = Reader::from('/path/to/my/file.csv'); count($reader); //returns 4 foreach ($reader as $offset => $record) { //iterates over the 4 records. } ``` -------------------------------- ### Insert Multiple Rows from Array and Traversable Source: https://csv.thephpleague.com/inserting Shows how to insert multiple rows using `insertAll`, accepting both arrays and `Traversable` objects. ```php use League\Csv\Writer; use ArrayIterator; $rows = [ [1, 2, 3], ['foo', 'bar', 'baz'], "'john','doe','john.doe@example.com'", new ToStringEnabledClass("john,doe,john.doe@example.com") ]; $writer = Writer::createFromFileObject(new SplTempFileObject()); $writer->insertAll($rows); //using an array $writer->insertAll(new ArrayIterator($rows)); //using a Traversable object ``` -------------------------------- ### Get CSV Records with Header Offset Source: https://csv.thephpleague.com/9.0/reader Set the header offset using `setHeaderOffset` to retrieve records as associative arrays with header keys. The output of `getRecords` depends on the header record selected. ```php use League\Csv\Reader; $reader = Reader::from('/path/to/my/file.csv', 'r'); $reader->setHeaderOffset(0); $records = $reader->getRecords(); foreach ($records as $offset => $record) { //$offset : represents the record offset //var_export($record) returns something like // array( // 'First Name' => 'jane', // 'Last Name' => 'doe', // 'E-mail' => 'jane.doe@example.com' // ); } ``` -------------------------------- ### Using FragmentFinder for Data Selection Source: https://csv.thephpleague.com/9.0/reader/statement Demonstrates how to use the `FragmentFinder` class to select data based on row and column expressions. The `find` method returns an iterator of `TabularDataReader` instances, while `findFirst` returns a single instance. Invalid selections are skipped. ```php use League\Csv\Reader; use League\Csv\FragmentFinder; $reader = Reader::from('/path/to/file.csv'); $finder = new FragmentFinder(); $finder->find('row=7-5;8-9', $reader); // return an Iterator $finder->findFirst('row=7-5;8-9', $reader); // return an TabularDataReader $finder->findFirstOrFail('row=7-5;8-9', $reader); // will throw ``` -------------------------------- ### Extract a Slice of Records Source: https://csv.thephpleague.com/9.0/reader/tabular-data-reader Extracts a specified number of records starting from a given offset. If the length is -1, it returns all records from the offset to the end. This method wraps Statement::offset and Statement::limit. ```PHP use League\Csv\Reader; use League\Csv\Statement; $reader = Reader::from('/path/to/my/file.csv', 'r'); $resultSet = (new Statement())->process($reader); $records = $resultSet->slice(10, 25); //$records is a TabularDataReader which contains up to 25 rows //starting at the offset 10 (the eleventh rows) ``` -------------------------------- ### Instantiate RecordCollection from league/csv Reader Source: https://csv.thephpleague.com/9.0/extensions/doctrine Create a Doctrine RecordCollection from a league/csv Reader instance. Ensure the CSV reader is configured with header offset and delimiter if necessary. ```php setHeaderOffset(0); $csv->setDelimiter(';'); $collection = new RecordCollection($csv); ``` -------------------------------- ### Reading CSV with Header and Records Source: https://csv.thephpleague.com/9.0/reader Demonstrates how to create a CSV reader from a file path, set the header offset, and retrieve records. The offset represents the record's position in the CSV file. ```php use League\Csv\Reader; $reader = Reader::from('/path/to/my/file.csv', 'r'); $reader->setHeaderOffset(0); $records = $reader->getRecords(); foreach ($records as $offset => $record) { //$offset : represents the record offset //var_export($record) returns something like // array( // 'First Name' => 'jane', // 'Last Name' => 'jane', // 'E-mail' => null // ); } ``` -------------------------------- ### Deprecated: Detect BOM using bom_match function Source: https://csv.thephpleague.com/9.0/connections/bom The `bom_match` function is deprecated and should be replaced by `Bom::tryFromSequence`. It returns the BOM sequence found at the start of a string or an empty string if none is found. ```PHP use League\Csv\ByteSequence; use function League\Csv\bom_match; bom_match('hello world!'); //returns '' bom_match(ByteSequence::BOM_UTF8.'hello world!'); //returns '\xEF\xBB\xBF' bom_match('hello world!'.ByteSequence::BOM_UTF16_BE); //returns '' ``` -------------------------------- ### Add Validator to Writer Source: https://csv.thephpleague.com/9.0/writer Example of adding a record validator to a Writer object. This validator checks if a record contains exactly 10 cells. Validators are applied after formatters and throw a `CannotInsertRecord` exception on failure. ```php use League\Csv\Writer; use League\Csv\CannotInsertRecord; $writer->addValidator(function (array $row): bool { return 10 == count($row); }, 'row_must_contain_10_cells'); try { $writer->insertOne(['john', 'doe', 'john.doe@example.com']); } catch (CannotInsertRecord $e) { echo $e->getName(); //displays 'row_must_contain_10_cells' $e->getData();//returns the invalid data ['john', 'doe', 'john.doe@example.com'] } ```