PHPackages                             flatmodel/laravel-csv-flatmodel - 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. [Database &amp; ORM](/categories/database)
4. /
5. flatmodel/laravel-csv-flatmodel

ActiveLibrary[Database &amp; ORM](/categories/database)

flatmodel/laravel-csv-flatmodel
===============================

Eloquent-inspired data modeling system for Laravel that works with CSV files

v1.0.0(3mo ago)00MITPHP

Since Feb 1Pushed 3mo ago1 watchersCompare

[ Source](https://github.com/Absorbing/laravel-flatmodel-csv)[ Packagist](https://packagist.org/packages/flatmodel/laravel-csv-flatmodel)[ RSS](/packages/flatmodel-laravel-csv-flatmodel/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (4)Versions (2)Used By (0)

 [![](/assets/FlatModel%20CSV.png)](/assets/FlatModel%20CSV.png)

FlatModel CSV is an Eloquent-inspired data modeling system for Laravel that works with CSV files.

It provides an expressive, familiar API for reading and writing flat data sources without relying on a database.

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

[](#installation)

Install with Composer into a new or existing Laravel project

```
composer require flatmodel/laravel-csv-flatmodel
```

Usage
-----

[](#usage)

A new CSV model can be made by running the artisan command which will prompt for a few details.

```
php artisan make:csv-model CsvModel
```

If instead you want to skip the prompts, the arguments can be provided instead;

```
php artisan make:csv-model CsvModel --path=csv\data.csv --primary=id
```

Providing a primary key is optional and can be skipped with the `--noprimary` flag or by leaving the prompt empty when prompted for a primary key.

Once the model is generated, it can be used similarly to standard models within Laravel

```
use App\Models\CsvModel

$model = (new CsvModel)
        ->where('active', true)
        ->pluck('id');
```

The methods are returned as instances of the `Illuminate\Support\Collection` class that those familiar with Laravel will be comfortable with. This also means that working with the data returned is simple and straightforward.

Opt-in Features
---------------

[](#opt-in-features)

FlatModel uses traits to provide optional functionality. Include these traits in your model as needed:

### Writable

[](#writable)

Enables write operations (insert, update, delete, upsert):

```
use FlatModel\CsvModel\Models\Model;
use FlatModel\CsvModel\Traits\Writable;

class EditableModel extends Model
{
    use Writable;

    protected string $path = 'data/users.csv';
    protected bool $writable = true;
}
```

### Backupable

[](#backupable)

Creates automatic timestamped backups before modifications:

```
use FlatModel\CsvModel\Models\Model;
use FlatModel\CsvModel\Traits\Writable;
use FlatModel\CsvModel\Traits\Backupable;

class BackedUpModel extends Model
{
    use Writable, Backupable;

    protected string $path = 'data/users.csv';
    protected bool $writable = true;
    protected bool $enableBackup = true;
}
```

### AppendOnly

[](#appendonly)

Restricts models to insert-only operations (no updates or deletes):

```
use FlatModel\CsvModel\Models\Model;
use FlatModel\CsvModel\Traits\Writable;
use FlatModel\CsvModel\Traits\AppendOnly;

class LogModel extends Model
{
    use Writable, AppendOnly;

    protected string $path = 'logs/activity.csv';
    protected bool $writable = true;
    protected bool $appendOnly = true;
}
```

**Note:** `AppendOnly` requires the `Writable` trait since it restricts write operations.

### HeaderAware

[](#headeraware)

Enables strict header validation and provides header utility methods:

```
use FlatModel\CsvModel\Models\Model;
use FlatModel\CsvModel\Traits\HeaderAware;

class StrictHeaderModel extends Model
{
    use HeaderAware;

    protected string $path = 'data/users.csv';
    protected bool $hasHeaders = true;  // CSV has header row
    protected array $headers = ['id', 'name', 'email'];  // Expected headers
    protected bool $strictHeaders = true;  // Enforce exact match
}
```

**Strict mode behavior:**

- Throws `HeaderMismatchException` if CSV headers don't exactly match `$headers`
- Useful for validating CSV file structure
- Requires both `$headers` to be defined and `$strictHeaders = true`

**Without HeaderAware:**

- Headers are still loaded/generated but not validated
- More flexible for varying CSV structures

Type Casting
------------

[](#type-casting)

CSV files store all data as strings. Use the `$cast` property to automatically convert values to specific types:

```
use FlatModel\CsvModel\Models\Model;

class Product extends Model
{
    protected string $path = 'data/products.csv';

    protected array $cast = [
        'id' => 'int',
        'price' => 'float',
        'in_stock' => 'bool',
        'name' => 'string',
    ];
}

// Values are automatically cast when reading
$product = (new Product())->where('id', 1)->first();
// $product['id'] is now an integer, not a string
// $product['price'] is now a float
// $product['in_stock'] is now a boolean
```

**Supported cast types:**

- `int` or `integer` - Cast to integer
- `float` or `double` - Cast to floating point number
- `bool` or `boolean` - Cast to boolean (handles "true", "false", "1", "0", etc.)
- `string` - Cast to string

Type casting is applied automatically when:

- Reading data with `get()`, `first()`, `pluck()`, etc.
- Writing data with `insert()`, `update()`, `upsert()`

Working with Headerless CSV Files
---------------------------------

[](#working-with-headerless-csv-files)

If your CSV file doesn't have a header row, set `$hasHeaders = false`:

### Option 1: Provide custom column names

[](#option-1-provide-custom-column-names)

```
class DataModel extends Model
{
    protected string $path = 'data/raw-data.csv';
    protected bool $hasHeaders = false;
    protected array $headers = ['id', 'name', 'value'];  // Custom column names
}

// Access with your custom names
$model = new DataModel();
$model->where('name', 'John')->get();
```

### Option 2: Use numeric indices

[](#option-2-use-numeric-indices)

```
class NumericModel extends Model
{
    protected string $path = 'data/raw-data.csv';
    protected bool $hasHeaders = false;
    // No headers defined - will use: ['0', '1', '2', ...]
}

// Access with numeric indices
$model = new NumericModel();
$model->where('0', 'John')->get();  // First column
$model->pluck('2');                 // Third column
```

### Header Row vs No Header Row

[](#header-row-vs-no-header-row)

```
# WITH header row ($hasHeaders = true) - DEFAULT
id,name,email
1,John,john@example.com
2,Jane,jane@example.com

# WITHOUT header row ($hasHeaders = false)
1,John,john@example.com
2,Jane,jane@example.com
```

Query Methods
-------------

[](#query-methods)

For interacting and querying data from the model, the following are available:

- `where(string $column, mixed $value)` - Filter rows by column value
- `first()` - Get the first matching row as an array, or null if no match
- `get()` - Get all matching rows as a Collection
- `pluck(string $column)` - Get a Collection of values from a specific column
- `select(string ...$columns)` - Select specific columns to return
- `value(string $column)` - Get the first value from a column, or null if not found

The model has a series of configurable properties that will enable or disable functionality.

PropertyTypeDescriptionDefault`$path`stringThe path of the file`$delimiter`stringThe delimiter used within the file`,``$enclosure`stringThe enclosure character used to wrap field values in the file`"``$escape`stringThe escape character used in the file`\``$stream`booleanIndicates whether the model operates in stream mode`false``$headers`arrayArray of column headers from the CSV file, if not provided will try to autodetect from file`[]``$hasHeaders`booleanIndicates whether the CSV file has a header row. If true, the first row is treated as column names. If false, data starts from the first row.`true``$strictHeaders`booleanEnables or disables strict header checking`false``$cast`arrayDefines type casting rules for columns. Valid cast types are `int`, `float`, `bool` and `string``[]``$writable`booleanIndicates whether the model is writable, if true the model can be used to write data back to the file. If false, the model is read-only`false``$appendOnly`booleanIndicates whether the model is append-only. If true the model will only have data added to the end of the file, updates cannot be written to models configured for append-only`false``$enableBackup`booleanEnables or disables automatic backups on modification of the file`false``$autoFlush`booleanIndicates whether the model should flush the data to the CSV file on every modification`false`Important

If `$autoFlush` is set to `false` (as it is by default), `flush()` should be manually called to persist the data to the file.

Writing, Mutating &amp; Flushing Data
-------------------------------------

[](#writing-mutating--flushing-data)

Writable models can be modified and saved back to the file using `flush()` or `save()` if `$autoFlush` is disabled by using `false`.

```
$model = new CsvModel;

$model->insert(['id' => 5, 'name' => 'Alex']);
$model->flush(); // Writes changes to the file
```

Updates and deletes are also possible using similarly named methods using functional filtering.

```
$model = new CsvModel;

// Update a matching row
$model->update(
    fn($row) => $row['id'] === 5,
    fn($row) => [...$row, 'name' => 'Alexa']
);

// Upsert: update if found, insert if not
$model->upsert(
    fn($row) => $row['id'] === 10,
    fn($row) => ['id' => 10, 'name' => 'New User']
);

// Delete matching rows
$model->delete(fn($row) => $row['id'] === 2);

// Save changes to disk
$model->flush();
```

Models can also be updated using more familiar array-based syntax.

```
$model->update(['id' => 5], ['name' => 'Alexa']);
$model->upsert(['id' => 10], ['id' => 10, 'name' => 'New User']);
$model->delete(['id' => 2]);
```

Warning

Models in stream mode cannot be written back to the file and are read-only. If an attempt is made to write to a model implementing stream mode, a `StreamWriteException` will be thrown.

Warning

If the model is in append-only mode, updates, upserts and deletes will throw an `AppendOnlyViolationException` exception.

Exception Handling
------------------

[](#exception-handling)

FlatModel uses custom exceptions to provide clear and understandable error context all extending a common base of `FlatModelException`.

ExceptionDescription`AppendOnlyViolationException`When updating or deleting a model flagged as append-only`BackupFailedException`When a backup fails prior to committing any changes to the file`CastingException`When a type casting operation fails for a column value`ColumnNotFoundException`When attempting to access a column that doesn't exist in the CSV`FileNotFoundException`When the specified CSV file cannot be found`FileWriteException`When writing changes to the CSV file fails`HeaderMismatchException`When headers don't match expected values in strict mode`InvalidHandleException`When attempting to read or write to an invalid file handle`InvalidRowFormatException`When a row doesn't match the expected format`MissingHeaderException`When required headers are missing from the CSV`PrimaryKeyMissingException`When a primary key operation is attempted without a defined key`StreamOpenException`When opening the CSV file in stream mode fails`StreamWriteException`When attempting to write to a model in stream mode`WriteNotAllowedException`When attempting to write to a read-only modelTesting
-------

[](#testing)

Run tests using Composer:

```
composer test
```

Or run PHPUnit directly:

```
vendor/bin/phpunit
```

License
-------

[](#license)

FlatModel is open-sourced software licensed under the [MIT license](LICENSE).

###  Health Score

32

—

LowBetter than 72% of packages

Maintenance81

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity34

Early-stage or recently created project

 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

Unknown

Total

1

Last Release

99d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/28628b59a544b9869394dde69543aa7dc1182316eb16bc9b3147da1622c0822d?d=identicon)[Absorbing](/maintainers/Absorbing)

---

Top Contributors

[![Absorbing](https://avatars.githubusercontent.com/u/1689075?v=4)](https://github.com/Absorbing "Absorbing (41 commits)")

---

Tags

csveloquentlaravellaravel-12laravel-modellaravel-packageormlaraveldatamodeleloquentcsvflatfile

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/flatmodel-laravel-csv-flatmodel/health.svg)

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

###  Alternatives

[mongodb/laravel-mongodb

A MongoDB based Eloquent model and Query builder for Laravel

7.1k7.2M71](/packages/mongodb-laravel-mongodb)[tucker-eric/eloquentfilter

An Eloquent way to filter Eloquent Models

1.8k4.8M26](/packages/tucker-eric-eloquentfilter)[kodeine/laravel-meta

Fluent Meta Data for Eloquent Models, as if it is a property on your model.

426756.0k9](/packages/kodeine-laravel-meta)[dyrynda/laravel-model-uuid

This package allows you to easily work with UUIDs in your Laravel models.

4802.8M8](/packages/dyrynda-laravel-model-uuid)[spiritix/lada-cache

A Redis based, automated and scalable database caching layer for Laravel

591444.8k2](/packages/spiritix-lada-cache)[pdphilip/elasticsearch

An Elasticsearch implementation of Laravel's Eloquent ORM

145360.2k4](/packages/pdphilip-elasticsearch)

PHPackages © 2026

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