Skip to content

Repository files navigation

Lxr Model

lxr/model is a small, standalone, Eloquent-inspired model class for PHP. It provides attribute access, mass-assignment rules, accessors and mutators, primitive casts, visibility controls, array access, and JSON serialization without requiring Laravel or another framework.

This package is an in-memory data model. It does not provide database persistence, a query builder, or Eloquent relationships.

Requirements

  • PHP 8.1 or newer
  • The mbstring PHP extension

Installation

Install the package with Composer:

composer require lxr/model

Quick start

Create a concrete model by extending Lxr\Model\Model:

<?php

use Lxr\Model\Model;

class User extends Model
{
    protected $fillable = [
        'name',
        'age',
        'active',
    ];

    protected $casts = [
        'age' => 'integer',
        'active' => 'boolean',
    ];

    protected $appends = [
        'display_name',
    ];

    public function setNameAttribute($value)
    {
        $this->attributes['name'] = trim((string) $value);
    }

    public function getDisplayNameAttribute($value)
    {
        return strtoupper((string) $this->name);
    }
}

$user = new User([
    'name' => '  Ada Lovelace  ',
    'age' => '36',
    'active' => 1,
]);

echo $user->name;       // Ada Lovelace
echo $user['age'];      // 36

$user->active = false;

print_r($user->toArray());

The resulting array is:

[
    'name' => 'Ada Lovelace',
    'age' => 36,
    'active' => false,
    'display_name' => 'ADA LOVELACE',
]

Attributes

Attributes can be read and written using properties, array syntax, or explicit methods:

$user->name = 'Grace Hopper';
$user['age'] = 40;

echo $user->name;
echo $user['age'];
echo $user->getAttribute('active');

$user->setAttribute('active', true);
unset($user['age']);

getAttributes() returns the model's raw, stored attributes. Accessors and casts are applied when values are read or converted to an array.

Mass assignment

Pass attributes to the constructor or use fill():

$user = new User(['name' => 'Ada']);

$user->fill([
    'name' => 'Grace',
    'age' => 40,
]);

Use $fillable to allow only selected keys:

class User extends Model
{
    protected $fillable = ['name', 'age'];
}

Use $guarded to reject selected keys, or ['*'] to guard every attribute:

class User extends Model
{
    protected $guarded = ['is_admin'];
}

When neither list is configured, all attributes are mass assignable. If $fillable is configured, other keys are silently discarded. A totally guarded model throws Lxr\Model\MassAssignmentException when filled.

Trusted data can bypass these rules with forceFill():

$user->forceFill(['is_admin' => true]);

You can also temporarily disable guarding for a callback:

User::unguarded(function () use ($user) {
    $user->fill(['is_admin' => true]);
});

Accessors and mutators

Define a get{Attribute}Attribute method to transform a value when it is read:

public function getNameAttribute($value)
{
    return strtoupper((string) $value);
}

Define a set{Attribute}Attribute method to transform a value before it is stored:

public function setNameAttribute($value)
{
    $this->attributes['name'] = trim((string) $value);
}

Snake-case keys are mapped to StudlyCase method names. For example, display_name uses getDisplayNameAttribute().

Casts

Declare primitive casts using the $casts property:

protected $casts = [
    'age' => 'integer',
    'score' => 'float',
    'active' => 'boolean',
    'reference' => 'string',
];

Supported read casts are:

  • int, integer
  • real, float, double
  • string
  • bool, boolean

Accessors take precedence over casts for the same attribute.

Array and JSON serialization

Models implement JsonSerializable and can be converted directly:

$array = $user->toArray();
$json = $user->toJson();
$json = json_encode($user);
$json = (string) $user;

Hide attributes from serialized output with $hidden:

protected $hidden = ['password', 'token'];

Alternatively, expose only selected attributes with $visible:

protected $visible = ['id', 'name'];

These lists can also be changed at runtime:

$user->setHidden(['token']);
$user->addHidden('password');
$user->withHidden('token');

$user->setVisible(['id', 'name']);
$user->addVisible('email');

Append computed accessor values with $appends or setAppends():

protected $appends = ['display_name'];

// Or at runtime:
$user->setAppends(['display_name']);

Hydration and replication

Create several model instances from arrays with hydrate():

$users = User::hydrate([
    ['name' => 'Ada', 'age' => 36],
    ['name' => 'Grace', 'age' => 40],
]);

Create a copy and optionally exclude attributes with replicate():

$copy = $user->replicate();
$copyWithoutId = $user->replicate(['id']);

String helpers

Lxr\Model\StringHelpers contains the string operations used by the model:

use Lxr\Model\StringHelpers;

StringHelpers::upper('hello');          // HELLO
StringHelpers::lower('HELLO');          // hello
StringHelpers::ucfirst('hello world');  // Hello world
StringHelpers::studly('hello_world');   // HelloWorld
StringHelpers::snake('HelloWorld');     // hello_world
StringHelpers::snake('HelloWorld', '-'); // hello-world

Development

Install development dependencies and run the complete quality suite:

composer install
composer test

The individual checks are also available:

composer phpcs
composer phpstan
composer phpunit

License

Lxr Model is open-source software licensed under the MIT License.

About

Eloquent-like model class with no external dependencies. Inspired by jenssegers/model package.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages