PHP code example of ez-php / orm

1. Go to this page and download the library: Download ez-php/orm library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

ez-php / orm example snippets


$app->register(\EzPhp\Orm\EntityServiceProvider::class);
$app->register(\EzPhp\Orm\Schema\SchemaServiceProvider::class);

use EzPhp\Orm\Entity;

class User extends Entity
{
    protected static string $table      = 'users';
    protected static bool   $timestamps = true;
    protected static array  $fillable   = ['name', 'email'];
    protected static array  $casts      = ['age' => 'int'];
    // also: 'gold' => 'bigint' (BigInteger), 'price' => 'decimal:2' (BigDecimal) — needs ez-php/bignum
}

use EzPhp\Orm\AbstractRepository;

/**
 * @extends AbstractRepository<User>
 */
class UserRepository extends AbstractRepository
{
    protected function entityClass(): string
    {
        return User::class;
    }

    public function findByEmail(string $email): ?User
    {
        return $this->findOneBy('email', $email);
    }

    public function activeUsers(): array
    {
        return $this->query()->where('active', true)->orderBy('name')->get();
    }
}

$repo = $app->make(UserRepository::class);

// INSERT
$user = new User(['name' => 'Alice', 'email' => '[email protected]']);
$repo->save($user);

// UPDATE (only dirty columns)
$user->name = 'Bob';
$repo->save($user);

// DELETE
$repo->delete($user);

$user  = $repo->find(1);
$all   = $repo->findAll();
$alice = $repo->findByEmail('[email protected]');
$page  = $repo->query()->where('active', true)->paginate(perPage: 15, page: 1);

$repo->query()->where('active', true)->chunkById(500, function (array $users): void {
    foreach ($users as $user) { /* may update or delete $user */ }
});

foreach ($repo->query()->lazy(1000) as $user) { /* one page in memory at a time */ }

(new QueryBuilder($db, 'orders'))->lazy(1000, 'orders.id'); // raw rows; qualified key column

$qb->select('customer_id')->groupBy('customer_id')
   ->having('COUNT(*)', '>', 5)
   ->having('SUM(total)', '>=', 1000);

$qb->having('total) OR 1=1 --', 1);   // throws InvalidArgumentException
$qb->select('customer_id', 'COUNT(*) AS orders');
$qb->selectRaw('DATE(created_at) AS day');

class Post extends Entity
{
    protected static string $table       = 'posts';
    protected static bool   $softDeletes = true;
}

$repo->delete($post);           // sets deleted_at — row stays in the DB
$post->trashed();               // true after soft delete

// Include soft-deleted rows
$all = $repo->withTrashed()->get();
$deleted = $repo->onlyTrashed()->get();

final class PostRepository extends AbstractRepository
{
    public function __construct(private readonly UserRepository $users, ?DatabaseInterface $db = null)
    {
        parent::__construct($db);
    }

    protected function entityClass(): string { return Post::class; }

    /** @return EntityBelongsTo<User> */
    public function author(Post $post): EntityBelongsTo
    {
        // FK on the post, PK on the user, the post's FK value
        return $this->belongsTo($this->users, 'user_id', 'id', $post->getAttribute('user_id'));
    }
}

// Lazy load
$author = $postRepo->author($post)->getResult();

// Eager load (avoids N+1)
$posts = $postRepo->query()->with('author')->get();

use EzPhp\Orm\Relations\RelationBatcher;

$batcher = new RelationBatcher(); // one per request/unit of work — it memoizes by key
$pending = array_map(fn ($post) => $batcher->belongsTo($postRepo->author($post)), $posts);
$authors = array_map(fn ($d) => $d->get(), $pending); // a single users query

$pending = array_map(fn ($user) => $batcher->belongsToMany($userRepo->tags($user)), $users);
$tags = array_map(fn ($d) => $d->get(), $pending); // one tags ⋈ user_tags query

use EzPhp\Orm\CastableInterface;

class Money implements CastableInterface
{
    public function __construct(private readonly int $cents) {}

    public static function castFrom(mixed $value): static
    {
        return new self((int) $value);
    }

    public function castTo(): mixed
    {
        return $this->cents;
    }
}

class Product extends Entity
{
    protected static array $casts = ['price' => Money::class];
}

use EzPhp\Orm\EntityObserverInterface;
use EzPhp\Orm\ObservableRepositoryTrait;

class AuditObserver implements EntityObserverInterface
{
    public function creating(object $entity): void {}
    public function created(object $entity): void { /* log insert */ }
    public function updating(object $entity): void {}
    public function updated(object $entity): void { /* log update */ }
    public function deleting(object $entity): void {}
    public function deleted(object $entity): void { /* log delete */ }
}

class UserRepository extends AbstractRepository
{
    use ObservableRepositoryTrait;
    // ...
}

$repo->observe(new AuditObserver());

/** @extends AppendOnlyRepository<LoginEvent> */
final class LoginEventRepository extends AppendOnlyRepository
{
    protected function entityClass(): string
    {
        return LoginEvent::class;
    }
}

$event = $repository->create(['user_id' => 7, 'ip' => '203.0.113.9']);

final class User extends Entity
{
    use TypedAttributes;

    public function age(): int { return $this->getInt('age'); }
    public function bio(): ?string { return $this->getNullableString('bio'); }
    public function verifiedAt(): ?DateTimeImmutable { return $this->getNullableDatetime('verified_at'); }
}

use EzPhp\Orm\Schema\Schema;

$schema = new Schema($db); // $db: DatabaseInterface

$schema->create('users', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('email')->unique();
    $table->timestamps();
});

$schema->table('users', function (Blueprint $table) {
    $table->string('phone')->nullable();
});

// natural and composite primary keys
$schema->create('artists', function (Blueprint $table) {
    $table->string('spotify_id', 64)->primary();
});

$schema->create('playlist_tracks', function (Blueprint $table) {
    $table->string('playlist_id', 64);
    $table->unsignedInteger('position');
    $table->primary(['playlist_id', 'position']);
});

$schema->drop('old_table');

use EzPhp\Orm\LoggingDatabase;

$db = new LoggingDatabase($realDb, $logger); // $logger implements EzPhp\Logging\LoggerInterface
$repo = new UserRepository($db);
bash
composer