PHPackages                             juanparati/csvreader - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [PDF &amp; Document Generation](/categories/documents)
4. /
5. juanparati/csvreader

ActiveLibrary[PDF &amp; Document Generation](/categories/documents)

juanparati/csvreader
====================

A light/fast CSV reader suitable for pretty large files.

4.5(3mo ago)3848↓33.3%1MITPHPPHP ^8.3CI passing

Since Sep 24Pushed 3mo ago3 watchersCompare

[ Source](https://github.com/juanparati/CSVReader)[ Packagist](https://packagist.org/packages/juanparati/csvreader)[ RSS](/packages/juanparati-csvreader/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (8)Dependencies (2)Versions (15)Used By (0)

[![Test passed](https://github.com/juanparati/CSVReader/actions/workflows/test.yml/badge.svg)](https://github.com/juanparati/CSVReader/actions/workflows/test.yml/badge.svg)

CSVReader
=========

[](#csvreader)

CSVReader is a lightweight and fast CSV reader library for PHP that is suitable for large size files.

CSVReader was developed for business and e-commerce environments where large CSV files with possible corrupted data can be ingested.

Installation
------------

[](#installation)

```
composer require juanparati/csvreader
```

Features
--------

[](#features)

- Easy to use.
- Small footprint (Read files as streams, so low memory is required).
- Read files with different encodings.
- Header column mapping based on string and number references.
- Auto column mapping.
- Support for different decimal separators (European ",", British ".").
- Type casting.
- Currency checking (Avoid misinterpreting corrupted or wrong currency values).
- Detect and ignore empty lines.
- Word segment extraction per column value.
- Word deletion per column value.
- Column value replacement.
- Value exclusion based on regular expression.
- Full UTF support.
- BOM support.
- Lightweight library without external dependencies (Except PHPUnit for testing).
- CSV format auto-detection (delimiter, enclosure, escape character, charset).

Usage
-----

[](#usage)

### Infer CSV format automatically and open file

[](#infer-csv-format-automatically-and-open-file)

```
/**
 * Example CSV file:
 *
 * name|price
 * John|10.50
 * Mary|20.00
 *
 */

// Open a CSV file with inferred parameters
$csv = new \Juanparati\CsvReader\CsvReader::open('file.csv');

// Extract rows sequentially
while ($row = $csv->read())
{
    ...
}
```

### Read CSV file with custom parameters

[](#read-csv-file-with-custom-parameters)

```
/**
 * Example CSV file:
 *
 * name;price
 * John;10.50
 * Mary;20.00
 *
 */

// Create CSVReader instance
$csv = new \Juanparati\CsvReader\CsvReader(
    file: 'file.csv',       // File path
    delimiter: ';',         // Column delimiter (Default semicolon)
    enclosureChar: '"',     // Text enclosure (Default double quotes)
    charset: 'UTF-8',       // Charset (Default auto-detect)
    escapeChar: '\\',       // Escape character (Default backslash)
    excludeField: 'exclude' // Name of the field used for flagging rows (Default: 'exclude')
    streamFilters: []       // Stream filters (Default: [])
);

// Automatic column mapping
$csv->setAutomaticMapField(
    0   // Define where the headline starts. Default: 0 (first line)
);

// Extract rows sequentially
while ($row = $csv->read())
{
    echo 'Name: ' . $row['name'];
    echo 'Price: ' . $row['price'];
}
```

#### Column separators

[](#column-separators)

Separators are set as string or constant representation.

SeparatorsConstant;\\Juanparati\\CsvReader\\CsvReader::DELIMITER\_SEMICOLON,\\Juanparati\\CsvReader\\CsvReader::DELIMITER\_COMMA|\\Juanparati\\CsvReader\\CsvReader::DELIMITER\_PIPE\\t\\Juanparati\\CsvReader\\CsvReader::DELIMITER\_TAB^\\Juanparati\\CsvReader\\CsvReader::DELIMITER\_CARET&amp;\\Juanparati\\CsvReader\\CsvReader::DELIMITER\_AMPERSANDIt's possible to use all kinds of separators, so it is not limited to the enumerated ones.

#### String enclosures

[](#string-enclosures)

EnclosureConstant~\\Juanparati\\CsvReader\\CsvReader::ENCLOSURE\_TILDES"\\Juanparati\\CsvReader\\CsvReader::ENCLOSURE\_QUOTESNo enclosure\\Juanparati\\CsvReader\\CsvReader::ENCLOSURE\_NONEEnclosure none is used when strings in CSV are not enclosed by any kind of character.

### Set custom field maps

[](#set-custom-field-maps)

```
// Define a custom map
$csv->setMapFields([
    'name' => new \Juanparati\CsvReader\FieldMaps\CsvFieldString(
        'Firstname'
    ),
    'price' => new \Juanparati\CsvReader\FieldMaps\CsvFieldDecimal(
        'Retailprice', \Juanparati\CsvReader\CsvReader::DECIMAL_SEP_COMMA
    )
],
    0   // Define where the headline starts. Default: 0 (first line)
);

// Extract rows sequentially
while ($row = $csv->read())
{
    echo 'Name: ' . $row['name'];
    echo 'Price: ' . $row['price'];
}
```

Custom field map (For CSV without header)
-----------------------------------------

[](#custom-field-map-for-csv-without-header)

```
$csv = new \Juanparati\CsvReader\CsvReader(
    file: 'file.csv',     // File path
    delimiter: ';'        // Column delimiter
);

// Define a custom map
$csv->setMapFields([
    'name' => new \Juanparati\CsvReader\FieldMaps\CsvFieldString(
        0   // Column 0
    ),
    'price' => new \Juanparati\CsvReader\FieldMaps\CsvFieldDecimal(
        3,  // Column 3
        \Juanparati\CsvReader\CsvReader::DECIMAL_SEP_COMMA
    ),
]);

while ($row = $csv->read(0)) {  // Read from line 0 instead of 1 because the header is not present
 ...
}
```

### Field map types

[](#field-map-types)

TypeDescription\\Juanparati\\CsvReader\\FieldMaps\\CsvFieldAutoInfer automatically column\\Juanparati\\CsvReader\\FieldMaps\\CsvFieldBoolBoolean column\\Juanparati\\CsvReader\\FieldMaps\\CsvFieldDecimalCurrency column\\Juanparati\\CsvReader\\FieldMaps\\CsvFieldIntInt column\\Juanparati\\CsvReader\\FieldMaps\\CsvFieldStringString column#### CsvFieldDecimal

[](#csvfielddecimal)

It's possible to define a decimal separator for currency columns.

Decimal separatorConstant.CsvFieldDecimal::DECIMAL\_SEP\_POINT,CsvFieldDecimal::DECIMAL\_SEP\_COMMA'CsvFieldDecimal::DECIMAL\_SEP\_APOSTROPHE⎖CsvFieldDecimal::DECIMAL\_SEP\_APOSTROPHE\_9995\_CsvFieldDecimal::DECIMAL\_SEP\_UNDERSCORE٫CsvFieldDecimal::DECIMAL\_SEP\_ARABIC### Remove characters from columns

[](#remove-characters-from-columns)

Sometimes it is required to remove certain characters on a specific column.

```
// Remove 'EUR' and '€' from column
$csv->setMapField([
    'price' => (new \Juanparati\CsvReader\FieldMaps\CsvFieldDecimal(
        0   // Column 0
    ))->setRemoveRule(['EUR', '€']),
]);
```

```
// Remove all prices higher than 100
$csv->setMapField([
    'price' => (new \Juanparati\CsvReader\FieldMaps\CsvFieldDecimal(
        0   // Column 0
    ))->setRemoveRule(fn($price) => $price > 100),
]);
```

`setRemoveRule` accepts strings, arrays and callbacks.

### Replace characters from the column

[](#replace-characters-from-the-column)

```
// Replace "Mr." by "Señor"
$csv->setMapField([
    'name' => (new \Juanparati\CsvReader\FieldMaps\CsvFieldString(
        'Firstname'
    ))->setReplaceRule('Mr.', 'Señor')
]);
```

### Exclude flag

[](#exclude-flag)

Sometimes it's convenient to flag rows according to the column data.

```
// Exclude all names that equal to John
$csv->setMapField([
    'name' => (new \Juanparati\CsvReader\FieldMaps\CsvFieldString(
        'Firstname'
    ))->setExclusionRule('John')
]);
```

In this example every time that column "name" has the word "John", the virtual column "exclude" will contain the value "true" (boolean).

`setExclusionRule` accepts strings, arrays and callbacks.

### Apply stream filters

[](#apply-stream-filters)

It's possible to apply stream filters to the CSV file. Filter streams are applied before the charset conversion.

```
$filters = [
    new \Juanparati\CsvReader\CsvStreamFilter('zlib.inflate'),
];

$csv = new \Juanparati\CsvReader\CsvReader(
    file: 'file.csv',
    streamFilters: $filter
);
```

### Charset and UTF Support

[](#charset-and-utf-support)

CSVReader automatically detects and handles UTF-16 and UTF-32 encoded files with and without BOM.

The default charset is UTF-8.

```
// Automatic detection for files that contains BOM (Fallback is UTF-8)
$csv = new \Juanparati\CsvReader\CsvReader('utf16-file.csv');

// The library automatically:
// 1. Detects the BOM (UTF-16LE, UTF-16BE...)
// 2. Applies the appropriate stream filter for conversion
// 3. Processes the file as UTF-8 internally

// You can check the detected BOM information
$encodingInfo = $csv->info()['encoding'];
echo "Has BOM" . ($encodingInfo['bom'] ? 'Yes' : 'No');
echo "Charset: {$encodingInfo['charset'}"; // e.g., "UTF-16LE"
```

Sometimes it's necessary to force a specific charset for files that don't contain a BOM passing the charset as a parameter. Example:

```
// Create CSVReader instance
$csv = new \Juanparati\CsvReader\CsvReader(
    file: 'file.csv',       // File path
    charset: 'UTF-16',      // Charset (Default auto-detect)
);
```

### File information

[](#file-information)

It's possible to get the current pointer position in bytes calling to the "tellPosition" method. To obtain the file stat, a call to the "info" method will return the file stat (See ).

```
$csv = new \Juanparati\CsvReader\CsvReader('file.csv');
echo 'Current byte position ' . $csv->tellPosition() . ' of ' . $csv->info()['file']['size'];
```

Backers
-------

[](#backers)

- [Matchbanker.es](https://matchbanker.es)

###  Health Score

53

—

FairBetter than 97% of packages

Maintenance79

Regular maintenance activity

Popularity23

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity84

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~206 days

Recently: every ~16 days

Total

14

Last Release

109d ago

Major Versions

0.99 → 1.02018-09-30

1.x-dev → 2.x-dev2025-11-17

2.0 → 3.02025-11-21

3.x-dev → 4.02025-11-26

PHP version history (2 changes)0.9PHP &gt;=7.0.1

2.x-devPHP ^8.3

### Community

Maintainers

![](https://www.gravatar.com/avatar/4caf72b4d969cfb8cdfbdc1d594c85b51c9316caf76b80aa0f9de7e3736cf59f?d=identicon)[juanparati](/maintainers/juanparati)

---

Top Contributors

[![juanparati](https://avatars.githubusercontent.com/u/835173?v=4)](https://github.com/juanparati "juanparati (18 commits)")

---

Tags

streamcsvreaderquick

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/juanparati-csvreader/health.svg)

```
[![Health](https://phpackages.com/badges/juanparati-csvreader/health.svg)](https://phpackages.com/packages/juanparati-csvreader)
```

###  Alternatives

[openspout/openspout

PHP Library to read and write spreadsheet files (CSV, XLSX and ODS), in a fast and scalable way

1.2k57.6M131](/packages/openspout-openspout)[rodenastyle/stream-parser

PHP Multiformat Streaming Parser

443195.7k2](/packages/rodenastyle-stream-parser)[dcat/easy-excel

使用简单实用的语义化接口快速读写Excel文件

155373.4k24](/packages/dcat-easy-excel)[csanquer/colibri-csv

Lightweight and performant CSV reader and writer library

16161.7k4](/packages/csanquer-colibri-csv)[seine/seine

Seine - Write spreadsheets of various formats to a stream

1270.3k](/packages/seine-seine)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
