A object relational mapper with a query builder and out of box support for MySQL databases.
composer require asko/orm
To start with create your base model class that your actual data models will be extending, like so:
use Asko\Orm\BaseModel;
use Asko\Orm\Drivers\MysqlDriver;
/**
* @template T
* @extends BaseModel<T>
*/
class Model extends BaseModel
{
public function __construct()
{
parent::__construct(new MysqlDriver(
host: "",
name: "",
user: "",
password: "",
port: 3006
));
}
}
And then you can create all your data models like this:
use Asko\Orm\Column;
/**
* @extends Model<User>
*/
class User extends Model
{
protected static string $_table = "users";
protected static string $_identifier = "id";
#[Column]
public int $id;
#[Column]
public string $name;
#[Column]
public string $email;
}
And woalaa, you have an ORM mapping data classes to tables in the database all with full type support (works especially well with PHPStan).
Note that the $_identifier
should match the name of the primary key column, which in the above case is id
, and the $_table
should match the name of the database table, naturally. The other properties here represent the columns of the table, these will be populated by the ORM automatically when querying data and have to have the Column
attribute.
You can query for data using the numerous query builder methods built into ORM.
An example query looks like this:
$user = (new User)
->query()
->where('id', '=', 1)
->first();
Although because we use the primary key identifier to search for the user, the above could be simplified as:
$user = (new User)->find(1);
Where clause to filter the results.
Usage:
(new User)->query()->where('id', '=', 1);
// or
(new User)->query()->where('id', '>', 1);
Same as where
but with AND
operator.
Usage:
(new User)->query()->where('id', '=', 1)->andWhere('email', '=', '[email protected]');
Same as where
but with OR
operator.
Usage:
(new User)->query()->where('id', '=', 1)->orWhere('email', '=', '[email protected]');
Order the results by a column.
Usage:
(new User)->query()->orderBy('id', 'asc');
Limit the number of results.
Usage:
(new User)->query()->limit(10);
Offset the results.
Usage:
(new User)->query()->offset(10);
Join another table.
Usage:
(new User)->query()->join('posts', 'posts.user_id', '=', 'users.id');
Join another table with a left join.
Usage:
(new User)->query()->leftJoin('posts', 'posts.user_id', '=', 'users.id');
Join another table with a right join.
Usage:
(new User)->query()->rightJoin('posts', 'posts.user_id', '=', 'users.id');
Join another table with an inner join.
Usage:
(new User)->query()->innerJoin('posts', 'posts.user_id', '=', 'users.id');
Join another table with an outer join.
Usage:
(new User)->query()->outerJoin('posts', 'posts.user_id', '=', 'users.id');
Add a raw SQL to the query.
Usage:
(new User)->query()->raw('WHERE id = ?', [1]);
Get all the results.
Usage:
(new User)->query()->get();
Get the first result.
Usage:
(new User)->query()->first();
Get the last result.
Usage:
(new User)->query()->last();
To create a new record in the database, you can do the following:
$user = new User;
$user->name = "John Smith";
$user->email = "[email protected]"
$user->store();
To update a record in the database, you can do the following:
$user = (new User)->find(1);
$user->name = "John Doe";
$user->store();
To delete a record in the database, you can do the following:
$user = (new User)->find(1);
$user->delete();
ORM comes with the MySQL driver already built in, but if you wish to extend the ORM to support other databases, you can do so by creating a new driver class that implements the ConnectionDriver
interface, and if you need to also build a new query builder due to syntax differences with the MySQL query builder, you can do so by creating a new query builder class that implements the QueryBuilder
interface.