PHPackages                             pdphilip/laravel-data-set - 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. pdphilip/laravel-data-set

ActiveLibrary

pdphilip/laravel-data-set
=========================

Eloquent style management of data sets in Laravel

v1.1.0(2mo ago)010.8kMITPHPPHP ^8.2CI passing

Since Oct 2Pushed 2mo agoCompare

[ Source](https://github.com/pdphilip/laravel-data-set)[ Packagist](https://packagist.org/packages/pdphilip/laravel-data-set)[ Docs](https://github.com/pdphilip/laravel-data-set)[ GitHub Sponsors](https://github.com/PDPhilip)[ RSS](/packages/pdphilip-laravel-data-set/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (3)Dependencies (25)Versions (6)Used By (0)

Laravel Data Set
================

[](#laravel-data-set)

[![Latest Version on Packagist](https://camo.githubusercontent.com/78c43c32989c8e7970b7f21bcbf07f8fd046d1c16a0c67cf9bf78955f329afe5/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f70647068696c69702f6c61726176656c2d646174612d7365742e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/pdphilip/laravel-data-set)[![GitHub Tests Action Status](https://camo.githubusercontent.com/fc0fed5377b3c8f561c54361a12984a24916379605e9c912a9f4ef6cfa1e9efc/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f70647068696c69702f6c61726176656c2d646174612d7365742f72756e2d74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/pdphilip/laravel-data-set/actions?query=workflow%3Arun-tests+branch%3Amain)[![GitHub phpstan Action Status](https://camo.githubusercontent.com/4b3a99d5e80f42170eaba745e9272e4a3dd7fd79c27415df9cf160140acff03a/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f70647068696c69702f6c61726176656c2d646174612d7365742f7068707374616e2e796d6c3f6272616e63683d6d61696e266c6162656c3d7068707374616e267374796c653d666c61742d737175617265)](https://github.com/pdphilip/laravel-data-set/actions?query=workflow%3Arun-tests+branch%3Amain)[![Total Downloads](https://camo.githubusercontent.com/eafc0029c318cf2a19a056ae21fbd7aaca64885fc5d0bff1e015a3fd23d3eac5/687474703a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f70647068696c69702f6c61726176656c2d646174612d7365742e737667)](https://packagist.org/packages/pdphilip/laravel-data-set)

Eloquent-style querying for in-memory data sets. No database required.

Replace static arrays and config lookups with a queryable, model-like interface. Ideal for reference data (countries, currencies, timezones), test fixtures, and anywhere you need Eloquent ergonomics without a database.

```
// Define your data set
class CountrySet extends DataSet
{
    protected string $modelClass = CountryDataModel::class;

    protected function data(): array
    {
        return [
            ['id' => 'US', 'name' => 'United States', 'currency' => 'USD', 'dial_code' => '+1'],
            ['id' => 'GB', 'name' => 'United Kingdom', 'currency' => 'GBP', 'dial_code' => '+44'],
            ['id' => 'DE', 'name' => 'Germany', 'currency' => 'EUR', 'dial_code' => '+49'],
            // ...
        ];
    }
}

// Query it like Eloquent
CountrySet::find('US')->name;                              // 'United States'
CountrySet::where('currency', 'EUR')->get();               // Collection of European countries
CountrySet::search('united')->pluck('name');               // ['United States', 'United Kingdom', ...]
CountrySet::where('dial_code', '+1')->first()->currency;   // 'USD'
```

Requirements
------------

[](#requirements)

- PHP 8.2+
- Laravel 10, 11, or 12

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

[](#installation)

```
composer require pdphilip/laravel-data-set
```

Quick Start
-----------

[](#quick-start)

### Inline usage

[](#inline-usage)

```
use PDPhilip\DataSet\DataSet;

$set = new DataSet;

$set->add(['name' => 'Alpha', 'status' => 'active', 'score' => 85]);
$set->add(['name' => 'Beta', 'status' => 'inactive', 'score' => 42]);
$set->add(['name' => 'Charlie', 'status' => 'active', 'score' => 91]);

$set->where('status', 'active')->count();                  // 2
$set->where('score', '>', 80)->orderBy('name')->get();     // Alpha, Charlie
$set->search('beta')->first()->score;                      // 42
```

### Extended data set (recommended)

[](#extended-data-set-recommended)

Create a dedicated class with seeded data:

```
use PDPhilip\DataSet\DataSet;

class TimezoneSet extends DataSet
{
    protected function data(): array
    {
        return [
            ['id' => 'UTC', 'name' => 'Coordinated Universal Time', 'offset' => '+00:00'],
            ['id' => 'EST', 'name' => 'Eastern Standard Time', 'offset' => '-05:00'],
            ['id' => 'PST', 'name' => 'Pacific Standard Time', 'offset' => '-08:00'],
            // ...
        ];
    }
}

// Static facade - data loads once, cached per request
TimezoneSet::find('EST')->name;        // 'Eastern Standard Time'
TimezoneSet::count();                  // 3
```

### Custom model class

[](#custom-model-class)

Type your data with a custom model for IDE autocompletion:

```
use PDPhilip\DataSet\DataModel;

/**
 * @property string $id
 * @property string $name
 * @property string $currency
 * @property string $dial_code
 */
class CountryDataModel extends DataModel {}
```

```
use PDPhilip\DataSet\DataSet;

class CountrySet extends DataSet
{
    protected string $modelClass = CountryDataModel::class;

    protected function data(): array
    {
        return [...];
    }
}
```

Now `CountrySet::find('US')` returns a `CountryDataModel` with typed properties.

### Relationship-like access

[](#relationship-like-access)

Use a DataSet as a pseudo-relationship on your Eloquent models:

```
class User extends Model
{
    public function country(): ?CountryDataModel
    {
        return CountrySet::find($this->country_code);
    }
}

$user->country()->name;       // 'United States'
$user->country()->dial_code;  // '+1'
```

API Reference
-------------

[](#api-reference)

### CRUD

[](#crud)

MethodReturnsDescription`create(array $attributes)``DataModel`Create an unsaved model instance`add(array $attributes)``DataModel`Create and save a model`insert(array $rows)``static`Bulk insert rows`$model->save()``static`Save or update a model`$model->delete()``void`Remove a model from the set```
// Create without saving
$model = $set->create(['name' => 'Draft']);
$model->status = 'pending';
$model->save();

// Create and save in one step
$model = $set->add(['name' => 'Ready', 'status' => 'active']);

// Bulk insert
$set->insert([
    ['name' => 'Alpha', 'status' => 'active'],
    ['name' => 'Beta', 'status' => 'inactive'],
]);

// Modify and re-save
$model = $set->find('us');
$model->name = 'Updated';
$model->save();

// Delete
$model->delete();
```

Records without an `id` get a UUID assigned automatically. Auto-generated IDs are hidden from `toArray()` output, so data round-trips cleanly (load from source, query, modify, export back). The ID is still accessible on the model for `find()`, `save()`, and `delete()` operations.

To use a custom primary key:

```
class MySet extends DataSet
{
    protected string $primaryKey = 'code';
}
```

### Query Methods

[](#query-methods)

All query methods return a new instance, leaving the original untouched.

MethodDescription`where(string $key, mixed $operator, mixed $value)`Filter by field. Supports `=`, `!=`, ``, ``, `=`, `like`, `===`, `!==``where(string $key, mixed $value)`Shorthand for `where($key, '=', $value)``whereNot(string $key, mixed $value)`Shorthand for `where($key, '!=', $value)``whereStrict(string $key, mixed $value)`Strict `===` comparison`whereIn(string $key, array $values)`Filter where field value is in array`whereNotIn(string $key, array $values)`Filter where field value is not in array`whereBetween(string $key, array $range)`Filter where field is between `[$min, $max]``whereNotBetween(string $key, array $range)`Filter where field is outside `[$min, $max]``whereNull(string $key)`Filter where field is null or missing`whereNotNull(string $key)`Filter where field is not null`search(string $term)`Case-insensitive search across all string fields`orderBy(string $key, string $direction)`Sort results (`asc` or `desc`)`orderByDesc(string $key)`Sort descending`groupBy(string $key)`Group results by field (applied on `get()`)`limit(int $count)`Limit result count`offset(int $count)`Skip first N results```
// Chaining
$set->where('status', 'active')
    ->where('score', '>', 50)
    ->orderBy('name')
    ->limit(10)
    ->get();

// Dot notation for nested data
$set->where('address.city', 'Sydney')->get();

// Array field membership
$set->insert([
    ['id' => '1', 'tags' => ['php', 'laravel']],
    ['id' => '2', 'tags' => ['js', 'react']],
]);
$set->where('tags', 'php')->get(); // Row 1

// Group by
$set->groupBy('browser')->get();
// => ['Chrome' => Collection, 'Firefox' => Collection, ...]

// Clone isolation - queries never pollute the base set
$active = $set->where('status', 'active');
$activeHigh = $active->where('score', '>', 80);
$activeLow = $active->where('score', '
