PHPackages                             inwebo/csv-reader - 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. inwebo/csv-reader

Abandoned → [inwebo/csv](/?search=inwebo%2Fcsv)Library[PDF &amp; Document Generation](/categories/documents)

inwebo/csv-reader
=================

This PHP class, provides a simple yet powerful way to read and process CSV files. Built as an extension of PHP's SplFileObject, it offers advanced features like column name mapping, data filtering, and sanitization to streamline your CSV processing tasks.

2.0.0(1w ago)213MITPHPPHP ^8.3CI passing

Since May 4Pushed 4w agoCompare

[ Source](https://github.com/inwebo/csv-reader)[ Packagist](https://packagist.org/packages/inwebo/csv-reader)[ Docs](https://github.com/inwebo/csv-reader)[ RSS](/packages/inwebo-csv-reader/feed)WikiDiscussions master Synced today

READMEChangelogDependencies (12)Versions (8)Used By (0)

PHP CSV Reader
==============

[](#php-csv-reader)

[![GitHub Actions Workflow Status](https://camo.githubusercontent.com/d5dbd1eb61734734065520f8d46c079290ac29e9c688680402c5e6c9142cc656/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f696e7765626f2f6373762d7265616465722f2e676974687562253246776f726b666c6f77732532466c6962726172792e796d6c3f6272616e63683d6d6173746572267374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/d5dbd1eb61734734065520f8d46c079290ac29e9c688680402c5e6c9142cc656/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f696e7765626f2f6373762d7265616465722f2e676974687562253246776f726b666c6f77732532466c6962726172792e796d6c3f6272616e63683d6d6173746572267374796c653d666c61742d737175617265)[![Packagist Version](https://camo.githubusercontent.com/d15c2bb030a0f523d4d2a1fb73edfb899126aaea5b99f25b9bc00f3e45bcf13d/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f696e7765626f2f6373762d7265616465723f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/d15c2bb030a0f523d4d2a1fb73edfb899126aaea5b99f25b9bc00f3e45bcf13d/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f696e7765626f2f6373762d7265616465723f7374796c653d666c61742d737175617265)[![Packagist Downloads](https://camo.githubusercontent.com/a0e440d149ddee686dcd741b09d2cc29cef965a54de6116fdbd8ad4d7d2b018b/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64642f696e7765626f2f6373762d7265616465723f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/a0e440d149ddee686dcd741b09d2cc29cef965a54de6116fdbd8ad4d7d2b018b/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64642f696e7765626f2f6373762d7265616465723f7374796c653d666c61742d737175617265)[![Packagist License](https://camo.githubusercontent.com/f9f18b61337484cfff63a1b3b9b6a5e5daaeeeb20c8829b8b93cf1ed60a84bae/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f696e7765626f2f6373762d7265616465723f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/f9f18b61337484cfff63a1b3b9b6a5e5daaeeeb20c8829b8b93cf1ed60a84bae/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f696e7765626f2f6373762d7265616465723f7374796c653d666c61742d737175617265)[![PHP Version](https://camo.githubusercontent.com/da638e86ec0beca6a1ceee108b1039437dafe92175b553f176a00135fc2869d9/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f696e7765626f2f6373762d7265616465723f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/da638e86ec0beca6a1ceee108b1039437dafe92175b553f176a00135fc2869d9/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f696e7765626f2f6373762d7265616465723f7374796c653d666c61742d737175617265)[![PHPStan Level](https://camo.githubusercontent.com/65c9bbcae389e4ca189f0239aa80ea655e986c4d7d4d586a15927056765c173f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048505374616e2d6c6576656c25323031302d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/65c9bbcae389e4ca189f0239aa80ea655e986c4d7d4d586a15927056765c173f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048505374616e2d6c6576656c25323031302d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)

This PHP class, `Inwebo\Csv\Reader`, provides a simple, really fast and low memory footprint way to read and process CSV files. Built as an extension of PHP's `SplFileObject`, it offers advanced features like **column name mapping**, **data filtering**, and **normalization** to streamline your CSV processing tasks.

Since it extends `\SplFileObject`, all methods to configure CSV reading (like `setCsvControl`) are available. See the [PHP documentation for SplFileObject](https://www.php.net/manual/en/class.splfileobject.php) for more details.

---

### Key Features

[](#key-features)

- **Column Name Mapping**: Automatically maps each line's data to an associative array using the CSV header as keys, making your code more readable and maintainable.
- **Data Normalization**: Apply one or more callable functions to each line to clean and format the data before it's used.
- **Data Filtering**: Use callable functions to validate and filter out rows that don't meet your criteria.
- **Generator-based Iteration**: Process large files efficiently using a `Generator` to iterate over lines without consuming too much memory.
- **Inherits `SplFileObject`**: Leverage all the native features and performance benefits of `SplFileObject` for file handling.

---

### Installation

[](#installation)

```
  composer req inwebo/csv-reader
```

Tests
-----

[](#tests)

```
  composer phpunit
```

PhpStan
-------

[](#phpstan)

```
  composer phpstan
```

> Level 10

---

### Usage

[](#usage)

#### Basic Reading

[](#basic-reading)

To get started, simply instantiate the `Reader` class with the path to your CSV file. By default, it assumes the first row contains column names.

```
use Inwebo\Csv\Reader;

$reader = new Reader('path/to/your/file.csv');

foreach ($reader->rows() as $row) {
    /** @var array{FirstName: string, LastName: string, Gender: string} $row */
    // $row will be an associative array, e.g., ['FirstName' => 'Philippe', 'LastName' => 'Petit', 'Gender' => 'M']
    print_r($row);
}
```

#### Disabling Column Names

[](#disabling-column-names)

If your CSV file does not have a header row, you can disable the column name mapping by setting the `hasHeaders` parameter to `false`.

```
use Inwebo\Csv\Reader;

$reader = new Reader('path/to/your/file.csv', hasHeaders: false);

foreach ($reader->rows() as $row) {
    // $row will be a numeric array, e.g., [0 => 'Philippe', 1 => 'Petit', 2 => 'M']
    print_r($row);
}
```

---

#### Manual Column Mapping

[](#manual-column-mapping)

For files without a header, you can manually define column names using the `setHeader()` method. This allows you to treat the data as an associative array even without a header row.

```
use Inwebo\Csv\Reader;

$reader = new Reader('path/to/your/file.csv', hasHeaders: false);

$reader
    ->setHeader(0, 'firstname')
    ->setHeader(1, 'lastname')
    ->setHeader(2, 'gender');

foreach ($reader->rows() as $row) {
    /** @var array{firstname: string, lastname: string, gender: string} $row */
    // $row will be an associative array, e.g., ['firstname' => 'Philippe', 'lastname' => 'Petit', 'gender' => 'M']
    print_r($row);
}
```

---

### Advanced Usage: Normalizers and Filters

[](#advanced-usage-normalizers-and-filters)

You can add multiple normalizers and filters to your `Reader` instance. They are executed sequentially in the order they are added.

#### Normalizers

[](#normalizers)

Normalizers are used to modify the data. The callback receives the line array by reference, allowing you to directly alter its values.

```
use Inwebo\Csv\Reader;

$reader = new Reader('path/to/your/file.csv');

// Add a normalizer to handle missing gender data
$reader->pushNormalizer(function (array &$row): void {
    /** @var array{Gender: string} $row */
    if (empty($row['Gender'])) {
        $row['Gender'] = 'U';
    }
});

// Add another normalizer to format the gender column
$reader->pushNormalizer(function (array &$row): void{
    /** @var array{Gender: string} $row */
    $gender = strtolower($row['Gender']);
    if (str_starts_with($gender, 'm')) {
        $row['Gender'] = 'M';
    } elseif (str_starts_with($gender, 'f')) {
        $row['Gender'] = 'F';
    }
});

// Add a normalizer to ensure Salary is an integer
$reader->pushNormalizer(function (array &$row): void {
    /** @var array{Salary: string|int|null} $row */
    $row['Salary'] = is_null($row['Salary']) ? 0 : (int) $row['Salary'];
});
```

#### Filters

[](#filters)

Filters are used to validate and exclude entire rows. If a filter returns `false`, the line will be skipped and will not be yielded by the generator.

```
use Inwebo\Csv\Reader;

$reader = new Reader('path/to/your/file.csv');

// Add a filter to only include rows where Salary is greater than 80000
$reader->pushFilter(function (array $row): bool {
    /** @var array{Salary: string|int|null} $row */
    return isset($row['Salary']) && (int) $row['Salary'] > 80000;
});

// Add another filter to only include users older than 25
$reader->pushFilter(function (array $row): bool {
    /** @var array{Age: string|int|null} $row */
    return isset($row['Age']) && (int) $row['Age'] > 25;
});
```

With both normalizers and filters in place, the processing loop becomes a clean, declarative statement of what you want to achieve.

```
foreach ($reader->rows() as $row) {
    // This line has passed all your checks and is ready to be used
    print_r($row);
}
```

#### Reading a Specific Range

[](#reading-a-specific-range)

You can also read a specific range of rows using the `rows()` method with `from` and `to` parameters.

```
use Inwebo\Csv\Reader;

$reader = new Reader('path/to/your/file.csv');

// Read rows from 10 to 20
foreach ($reader->rows(from: 10, to: 20) as $row) {
    print_r($row);
}
```

#### Reading a Specific Row

[](#reading-a-specific-row)

The `rowAt()` method allows you to retrieve a specific row by its index.

```
use Inwebo\Csv\Reader;

$reader = new Reader('path/to/your/file.csv');

// Retrieve the 5th row
$row = $reader->rowAt(5);
print_r($row);
```

---

### Realistic Scenario: Customer Migration

[](#realistic-scenario-customer-migration)

This scenario demonstrates a realistic use case: migrating a customer database from an old CSV file (`tests/Fixtures/example.csv`) to a new system.

We need to:

- Clean up first and last names (trimming, casing).
- Format phone numbers.
- Formalize genders to 'M' or 'F'.
- Filter for valid email addresses.
- Example 1: Only women with a salary &lt; 10,000.
- Example 2: Only men with a salary &gt; 22,500.

```
use Inwebo\Csv\Reader;

$reader = new Reader('tests/Fixtures/example.csv');

// 1. Clean names and surnames
$reader->pushNormalizer(function (array &$row): void {
    $row['FirstName'] = mb_convert_case(trim($row['FirstName']), MB_CASE_TITLE, "UTF-8");
    $row['LastName'] = mb_convert_case(trim($row['LastName']), MB_CASE_TITLE, "UTF-8");
});

// 2. Format phone numbers (basic example)
$reader->pushNormalizer(function (array &$row): void {
    if (!empty($row['Phone'])) {
        $row['Phone'] = str_replace(['.', ' ', '-', '+33'], '', $row['Phone']);
        if (strlen($row['Phone']) === 9) {
            $row['Phone'] = '0' . $row['Phone'];
        }
    }
});

// 3. Formalize genders (M/F)
$reader->pushNormalizer(function (array &$row): void {
    $gender = strtoupper(trim($row['Gender']));
    if (in_array($gender, ['M', 'MALE'])) {
        $row['Gender'] = 'M';
    } elseif (in_array($gender, ['F', 'FEMALE'])) {
        $row['Gender'] = 'F';
    } else {
        $row['Gender'] = 'U'; // Unknown
    }
});

// 4. Filter for valid emails
$reader->pushFilter(function (array $row): bool {
    return filter_var($row['Email'], FILTER_VALIDATE_EMAIL) !== false;
});

// Example 1: Women with salary < 10,000
$reader->pushFilter(function (array $row): bool {
    return $row['Gender'] === 'F' && (int)$row['Salary'] < 10000;
});

foreach ($reader->rows() as $row) {
    // Process matching women
}

// Example 2: Men with salary > 22,500
$reader->clearFilters(); // Clear previous filters if needed
// Re-apply common filters if necessary or create a new reader instance

$reader = new Reader('tests/Fixtures/example.csv');
// ... re-apply normalizers and email filter ...
$reader->pushFilter(function (array $row): bool {
    return $row['Gender'] === 'M' && (int)$row['Salary'] > 22500;
});

foreach ($reader->rows() as $row) {
    // Process matching men
}
```

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance92

Actively maintained with recent releases

Popularity8

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

 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 ~17 days

Total

6

Last Release

13d ago

Major Versions

1.1.0 → 2.0.02026-06-20

PHP version history (2 changes)1.0.3PHP ^8.3

1.0.0PHP ^8.1

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/845359?v=4)[Inwebo Veritas](/maintainers/inwebo)[@inwebo](https://github.com/inwebo)

---

Top Contributors

[![inwebo](https://avatars.githubusercontent.com/u/845359?v=4)](https://github.com/inwebo "inwebo (19 commits)")

---

Tags

csvcsv-filescsv-parsercsv-readercsv-readingkissphpphpcsvreaderspreadsheetfilterspletlsanitizedata processingcsv-importcsv parserfile reader

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/inwebo-csv-reader/health.svg)

```
[![Health](https://phpackages.com/badges/inwebo-csv-reader/health.svg)](https://phpackages.com/packages/inwebo-csv-reader)
```

###  Alternatives

[openspout/openspout

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

1.2k70.2M243](/packages/openspout-openspout)[avadim/fast-excel-reader

Lightweight and very fast XLSX Excel Spreadsheet and CSV Reader in PHP

107737.8k11](/packages/avadim-fast-excel-reader)

PHPackages © 2026

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