Skip to content

Models ​

Philosophy ​

Models are the single source of truth in Nexphant.

One definition generates:

  • Database schema
  • Migrations
  • OpenAPI specs
  • JSON Schema
  • Form metadata
  • IDE autocomplete

Basic Model ​

php
use Nexphant\Database\Model;
use Nexphant\Database\Attributes\{Table, Id, Column, CreatedAt, UpdatedAt};

#[Table('users')]
class User extends Model
{
    #[Id]
    public int $id;

    #[Column]
    public string $name;

    #[Column]
    public string $email;

    #[CreatedAt]
    public DateTimeImmutable $createdAt;

    #[UpdatedAt]
    public DateTimeImmutable $updatedAt;
}

Attributes ​

Table Definition ​

php
#[Table('users')]
#[Table('users', connection: 'mysql')]

Primary Key ​

php
#[Id]
public int $id;

#[Id(autoIncrement: false)]
public string $uuid;

Columns ​

php
#[Column]
public string $name;

#[Column('user_email')]
public string $email;

#[Column(type: 'text')]
public string $bio;

Constraints ​

php
#[Unique]
public string $email;

#[Nullable]
public ?string $phone;

#[DefaultValue('active')]
public string $status;

Validation Attributes ​

php
#[Email]
public string $email;

#[Length(min: 3, max: 100)]
public string $name;

#[Length(min: 8)]
public string $password;

Timestamps ​

php
#[CreatedAt]
public DateTimeImmutable $createdAt;

#[UpdatedAt]
public DateTimeImmutable $updatedAt;

#[DeletedAt]
public ?DateTimeImmutable $deletedAt;

Hidden Fields ​

php
#[Hidden]
public string $password;

#[Hidden]
public string $apiToken;

Type Casting ​

php
#[Cast('json')]
public array $metadata;

#[Cast('encrypted')]
public string $secret;

#[Cast('boolean')]
public bool $active;

Query Builder ​

Find ​

php
$user = User::query()->find(1);
$user = User::query()->where('email', $email)->first();
$user = User::query()->where('email', $email)->firstOrFail();

Get Multiple ​

php
$users = User::query()->get();
$users = User::query()->where('active', true)->get();
$users = User::query()->orderBy('name')->limit(10)->get();

Insert ​

php
$id = User::query()->insertGetId([
    'name' => 'Alice',
    'email' => 'alice@example.com',
]);

Update ​

php
User::query()
    ->where('id', $id)
    ->update(['name' => 'Alice Smith']);

Delete ​

php
User::query()->where('id', $id)->delete();

Pagination ​

php
$result = User::query()->paginate(page: 1, perPage: 20);

echo $result->total;       // total records
echo $result->currentPage; // current page
echo $result->lastPage;    // last page
$users = $result->data;    // array of User models

Transactions ​

php
use Nexphant\Database\DB;

DB::transaction(function () {
    User::query()->insert(['name' => 'Alice']);
    Post::query()->insert(['title' => 'Hello']);
});

No Magic ​

Nexphant models have no magic:

❌ No dynamic properties

php
$user->undefinedProperty; // Error

❌ No lazy loading

php
$user->posts; // Error - not defined

❌ No automatic relationships

php
$user->posts(); // Error - must define manually

✅ Explicit queries

php
$posts = Post::query()->where('user_id', $user->id)->get();

Fillable & Hidden ​

Fillable ​

Control mass assignment:

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

// Only name and email will be filled
$user = User::query()->create($request->all());

Hidden ​

Hide fields from JSON serialization:

php
#[Hidden]
public string $password;

$json = json_encode($user); // password excluded

Soft Deletes ​

php
use Nexphant\Database\Attributes\DeletedAt;

class Post extends Model
{
    #[DeletedAt]
    public ?DateTimeImmutable $deletedAt;
}

// Soft delete
Post::query()->where('id', $id)->delete();

// Include soft deleted
Post::query()->withTrashed()->get();

// Only soft deleted
Post::query()->onlyTrashed()->get();

// Permanent delete
Post::query()->where('id', $id)->forceDelete();

// Restore
Post::query()->where('id', $id)->restore();

Complete Example ​

php
use Nexphant\Database\Model;
use Nexphant\Database\Attributes\*;

#[Table('users')]
class User extends Model
{
    #[Id]
    public int $id;

    #[Email]
    #[Unique]
    #[Length(min: 3, max: 255)]
    public string $email;

    #[Length(min: 3, max: 100)]
    public string $name;

    #[Hidden]
    #[Length(min: 8)]
    public string $password;

    #[Nullable]
    public ?string $phone;

    #[Cast('json')]
    public array $settings;

    #[DefaultValue('active')]
    public string $status;

    #[CreatedAt]
    public DateTimeImmutable $createdAt;

    #[UpdatedAt]
    public DateTimeImmutable $updatedAt;

    #[DeletedAt]
    public ?DateTimeImmutable $deletedAt;
}

Usage:

php
// Create
$user = User::query()->insertGetId([
    'email' => 'alice@example.com',
    'name' => 'Alice',
    'password' => password_hash('secret', PASSWORD_DEFAULT),
    'settings' => ['theme' => 'dark'],
]);

// Find
$user = User::query()->find($user);

// Update
User::query()
    ->where('id', $user)
    ->update(['name' => 'Alice Smith']);

// Soft delete
User::query()->where('id', $user)->delete();

// JSON (password hidden)
echo json_encode($user);

Migration Generation ​

Models generate migrations automatically:

bash
php nexphant migrate:diff

Framework:

  1. Reads model attributes
  2. Compares with database schema
  3. Generates migration file

Next Steps ​

Released under the MIT License.