Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/betoalien/Lyger-PHP-Framework/llms.txt

Use this file to discover all available pages before exploring further.

Introduction

Eloquent is Lyger’s implementation of the Active Record pattern, providing an elegant and expressive way to interact with your database. Each database table has a corresponding Model class that is used to interact with that table.

Defining Models

Basic Model Definition

Create a model by extending the Lyger\Database\Model class:
app/Models/User.php
<?php

namespace App\Models;

use Lyger\Database\Model;

class User extends Model
{
    protected string $table = 'users';
    protected string $primaryKey = 'id';
    protected array $fillable = ['name', 'email', 'password'];
    protected array $hidden = ['password'];
    protected bool $timestamps = true;
}
If you don’t specify a $table property, Eloquent will automatically use the lowercase, pluralized class name (e.g., User becomes users).

Model Properties

Table Name

// Explicitly set table name
protected string $table = 'users';

Primary Key

// Default is 'id'
protected string $primaryKey = 'id';

// Custom primary key
protected string $primaryKey = 'user_id';

Fillable Attributes

Define which attributes can be mass-assigned:
protected array $fillable = ['name', 'email', 'password', 'status'];
Only attributes listed in $fillable can be set via create() or fill() methods. This protects against mass-assignment vulnerabilities.

Hidden Attributes

Hide attributes when converting to array or JSON:
protected array $hidden = ['password', 'secret_token'];

Timestamps

// Enable automatic timestamp management (default: true)
protected bool $timestamps = true;

// Disable timestamps
protected bool $timestamps = false;
When enabled, Eloquent automatically manages created_at and updated_at columns.

Attribute Casting

Cast attributes to specific types:
protected array $casts = [
    'id' => 'int',
    'email_verified' => 'bool',
    'price' => 'float',
    'options' => 'array',
    'metadata' => 'json',
    'published_at' => 'datetime'
];
Supported casts: int, integer, float, double, bool, boolean, string, array, json, datetime, date

Retrieving Models

Find by Primary Key

// Find by ID (returns null if not found)
$user = User::find(1);

// Find or throw exception
$user = User::findOrFail(1); // Throws RuntimeException if not found

Retrieving All Records

$users = User::all();

foreach ($users as $user) {
    echo $user->name;
}

Using Query Builder Methods

All Query Builder methods are available on models:
// Where clauses
$activeUsers = User::query()
    ->where('status', '=', 'active')
    ->get();

// Ordering
$recentUsers = User::query()
    ->latest('created_at')
    ->limit(10)
    ->get();

// Multiple conditions
$admins = User::query()
    ->where('role', '=', 'admin')
    ->whereNotNull('email_verified_at')
    ->orderBy('name', 'ASC')
    ->get();

Creating Models

Using Create Method

$user = User::create([
    'name' => 'John Doe',
    'email' => 'john@example.com',
    'password' => password_hash('secret', PASSWORD_DEFAULT)
]);

Using Save Method

$user = new User();
$user->name = 'Jane Doe';
$user->email = 'jane@example.com';
$user->password = password_hash('secret', PASSWORD_DEFAULT);
$user->save();

Using Fill Method

$user = new User();
$user->fill([
    'name' => 'Bob Smith',
    'email' => 'bob@example.com'
]);
$user->password = password_hash('secret', PASSWORD_DEFAULT);
$user->save();
The create() and fill() methods only work with attributes listed in the $fillable property.

Updating Models

Update Using Save

$user = User::find(1);
$user->name = 'Updated Name';
$user->email = 'newemail@example.com';
$user->save();

Mass Update via Query

User::query()
    ->where('status', '=', 'pending')
    ->update(['status' => 'active']);

Deleting Models

Delete Single Model

$user = User::find(1);
$user->delete();

Delete via Query

User::query()
    ->where('status', '=', 'inactive')
    ->where('last_login', '<', date('Y-m-d', strtotime('-1 year')))
    ->delete();

Accessing Attributes

Magic Properties

$user = User::find(1);

// Get attributes
echo $user->name;
echo $user->email;

// Set attributes
$user->name = 'New Name';
$user->status = 'active';

Array Access

// Check if attribute exists
if (isset($user->email)) {
    echo $user->email;
}

// Unset attribute
unset($user->temporary_field);

Serialization

To Array

$user = User::find(1);
$array = $user->toArray();

// Hidden attributes are excluded
// Casted attributes are converted to their target types

To JSON

$user = User::find(1);
$json = $user->toJson();

// Or with options
$json = $user->toJson(JSON_PRETTY_PRINT);

Collections

Eloquent returns a Collection instance for multi-record results:
$users = User::all();

// Collection methods
$count = $users->count();
$first = $users->first();
$last = $users->last();
$isEmpty = $users->isEmpty();

// Map over collection
$names = $users->map(fn($user) => $user->name);

// Filter collection
$admins = $users->filter(fn($user) => $user->role === 'admin');

// Pluck specific attribute
$emails = $users->pluck('email');

// Where on collection
$active = $users->where('status', '=', 'active');

// Sort collection
$sorted = $users->sortBy('name');
$sortedDesc = $users->sortByDesc('created_at');

// Take first N items
$topTen = $users->take(10);

// Convert to array/JSON
$array = $users->toArray();
$json = $users->toJson();

Model Methods

Getting the Primary Key

$user = User::find(1);
$id = $user->getKey(); // Returns primary key value
$keyName = $user->getPrimaryKey(); // Returns 'id'

Getting the Table Name

$tableName = $user->getTableName();
// Or statically
$tableName = User::getTable();

Complete Example

Here’s a comprehensive example demonstrating Eloquent usage:
app/Models/Post.php
<?php

namespace App\Models;

use Lyger\Database\Model;

class Post extends Model
{
    protected string $table = 'posts';
    
    protected array $fillable = [
        'title',
        'slug',
        'content',
        'status',
        'user_id',
        'published_at'
    ];
    
    protected array $hidden = [
        'deleted_at'
    ];
    
    protected array $casts = [
        'id' => 'int',
        'user_id' => 'int',
        'published' => 'bool',
        'published_at' => 'datetime',
        'metadata' => 'json'
    ];
    
    protected bool $timestamps = true;
}
use App\Models\Post;

// Create a new post
$post = Post::create([
    'title' => 'Getting Started with Lyger',
    'slug' => 'getting-started-with-lyger',
    'content' => 'Lyger is a modern PHP framework...',
    'status' => 'published',
    'user_id' => 1,
    'published_at' => date('Y-m-d H:i:s')
]);

// Find and update
$post = Post::find(1);
$post->title = 'Updated Title';
$post->save();

// Query posts
$publishedPosts = Post::query()
    ->where('status', '=', 'published')
    ->whereNotNull('published_at')
    ->latest('published_at')
    ->limit(10)
    ->get();

// Iterate over collection
foreach ($publishedPosts as $post) {
    echo "{$post->title} - {$post->published_at}\n";
}

// Get draft posts
$drafts = Post::query()
    ->where('status', '=', 'draft')
    ->where('user_id', '=', $userId)
    ->orderBy('created_at', 'DESC')
    ->get();

// Count posts
$totalPosts = Post::query()->count();
$publishedCount = Post::query()
    ->where('status', '=', 'published')
    ->count();

// Delete old drafts
Post::query()
    ->where('status', '=', 'draft')
    ->where('created_at', '<', date('Y-m-d', strtotime('-30 days')))
    ->delete();

Best Practices

1

Use Mass Assignment Protection

Always define $fillable to protect against mass-assignment vulnerabilities:
protected array $fillable = ['name', 'email', 'status'];
2

Hide Sensitive Data

Use $hidden to exclude sensitive attributes from arrays and JSON:
protected array $hidden = ['password', 'api_token'];
3

Use Type Casting

Cast attributes to appropriate types for better type safety:
protected array $casts = [
    'id' => 'int',
    'active' => 'bool',
    'options' => 'array'
];
4

Enable Timestamps

Let Eloquent manage timestamps automatically:
protected bool $timestamps = true;

Next Steps

Relationships

Define relationships between your models

Query Builder

Learn more about the underlying Query Builder