ORM

PointArt's ORM maps PHP classes to database tables using attributes. Extend Model, annotate your class, and get find(), save(), and delete() with no SQL. For more complex queries — dynamic finders, custom SQL, and count/exists operations — see Repositories.

Namespaces PointStart\ORM — Model
PointStart\Attributes — Entity, Column, Id

Defining a Model

Place model classes in app/models/. Annotate with #[Entity], mark columns with #[Column], and the primary key with #[Id]:

#[Entity('users')]
class User extends Model {
    #[Id]
    public ?int $id = null;

    #[Column('name', 'varchar')]
    public string $name;

    #[Column('email', 'varchar', nullable: true)]
    public ?string $email = null;
}

#[Entity]

ParameterTypeRequiredDescription
tableNamestringYesThe database table this class maps to

#[Id]

No parameters. Marks the primary key property — must be ?int, initialised to null. The value is set automatically after save() on insert.

#[Column]

ParameterTypeRequiredDescription
columnNamestringYesThe database column name
typestringYesColumn type hint (e.g. 'varchar', 'int', 'real')
nullableboolNoWhether the column accepts NULL. Default: false

Static Query Methods

MethodSQL Equivalent
User::find($id)SELECT * WHERE pk = ? LIMIT 1
User::findAll()SELECT *
User::findBy(['col' => $val], $order, $limit)SELECT * WHERE col = ? [ORDER/LIMIT]
User::findOne(['col' => $val])SELECT * WHERE col = ? LIMIT 1

Instance Methods

// Create and save
$user = new User();
$user->name  = 'Alice';
$user->email = '[email protected]';
$user->save();    // INSERT (id is null) → id set from lastInsertId

// Update
$user->name = 'Alice B.';
$user->save();    // UPDATE (id is not null)

// Delete
$user->delete();  // DELETE WHERE id = ?
MethodBehaviour
$entity->save()INSERT if primary key is null, UPDATE otherwise
$entity->delete()DELETE WHERE pk = ?

Database Connection

The PDO connection is created lazily on the first query. The driver is selected from config.php:

DriverDSN Format
sqlitesqlite:/path/to/database.sqlite
mysqlmysql:host=…;port=…;dbname=…;charset=…
pgsqlpgsql:host=…;port=…;dbname=…
Testing For unit tests, set Model::$pdo directly to inject an in-memory SQLite instance: Model::$pdo = new PDO('sqlite::memory:');

Next: Repositories →