Basic operations
Learn how to use the ORM
This version of the library is no longer maintained. Please consider upgrading to the latest release
Finding records by primary key
Finding a record by its primary key is done by using the find
method.
This method returns false
if no records were found.
$user = User::find(1);
if ($user !== false) {
// do something
}
If you want to find multiple records by their primary key, you can use the findMany
method which will return an array of models, or an empty array if no records were found.
This method takes as an argument an array containing primary key values.
$users = User::findMany([1, 2, 3]);
foreach ($users as $user) {
// do something
}
You can load all records from a model’s table by using the findAll
method.
$users = User::findAll();
foreach ($users as $user) {
// do something
}
You can specify which columns to be included by passing an array of column names
to the find
, findMany
or findAll
methods.
$user = User::find(1, ['name', 'age']);
$users = User::findMany([1, 2, 3], ['name', 'age']);
$users = User::findAll(['name', 'age']);
Accessing column values
Accessing the column values of the model is done by accessing the corresponding property of the model instance.
foreach (User::findAll() as $user) {
echo $user->name, PHP_EOL;
}
You can alias a column’s name by setting a $mapColumns
property on the model’s class.
class User extends BaseModel
{
protected $mapColumns = ['registration_email' => 'registrationEmail'];
}
In the above example, a column named registration_email
was mapped to registrationEmail
.
Now we can access the registrationEmail
property on a model instance to retrieve
the value of the registration_email
column.
foreach (User::findAll() as $user) {
echo $user->registrationEmail, PHP_EOL;
}
Mutators
Mutators allow to intercept and change the value that is going to be set to a property of the model.
Defining a mutator is done by creating a method that has the same name as the property,
followed by the Mutator
suffix.
class User extends BaseModel
{
public function passwordMutator($value)
{
return password_hash($value, PASSWORD_DEFAULT);
}
}
// ...
$user = new User;
$user->name = 'John Doe';
$user->password = $secret;
$user->save();
Accessors
Accessors allow you to intercept and modify the value returned by accessing a
property of a model. You can define an accessor for a model’s property by adding
a method with the same name as the property, followed by the Accessor
suffix.
class User extends BaseModel
{
public function registrationDateAccessor($value)
{
return new DateTime($value);
}
}
// ...
$user = User::find(1);
echo $user->registrationDate->format('Y-m-d H:i:s');
Type casting
You can cast a column’s value from one type to another by using the $cast
property.
The supported cast types are: integer
, float
, string
, boolean
, date
and array
.
class User extends BaseModel
{
protected $cast = ['is_admin' => 'boolean'];
protected $mapColumns = ['is_admin' => 'isAdmin'];
}
// ...
$user = User::find(1);
if ($user->isAdmin) {
// do something
}
The array type cast is used to deserialize JSON into a PHP array. You can modify that array and set it back as property and the array will be automatically serialized back into JSON.
class Page extends BaseModel
{
protected $cast = ['keywords' => 'array'];
}
// ...
$page = Page::find(1);
$keywords = $page->keywords;
if (!in_array('ORM', $keywords)) {
$keyowrds[] = 'ORM';
}
$page->keywords = $keywords;
$page->save();
Custom type casting
This feature is available starting with version 3.3.2
.
You can define a new casting type or how a casting operation is handled by using
the $castType
property. If your cast callback is a non-static method on the current class,
just use as a callback the method’s name prefixed with @
. The callback takes as arguments
the cast’s name and the value that needs to be casted.
class User extends BaseModel
{
protected $cast = [
'registration_date' => 'date',
'is_admin' => 'boolean',
];
protected $castType = [
'boolean' => [__CLASS__, 'castBoolean'],
'date' => '@castDate'
];
// Non-static handler
protected function castDate($cast, $value)
{
// ...
}
// Static handler
protected static function castBoolean($cast, $value)
{
// ...
}
}
Performing queries
Since model classes are basically build over a query builder, you can use them to
perform complex queries by adding filters, limits, joins or ordering criteria to your queries.
Retrieving the results of a query is done by using the all
method. The method returns
an array of models or an empty array if no records were found.
$users = User::where('age')->atLeast(18)
->orderBy('age')
->all();
Retrieving only the first result of a query is done by using the first
method.
This method returns false
if no records were found.
$user = User::where('age')->atLeast(18)
->orderBy('age')
->limit(1)
->first();
Query scopes
Scopes allow you to define sets of constraints that you can utilize by calling a single method.
Defining a scope is simply a matter of adding a method that contains the Scope
suffix.
Scopes must always return an instance of the query builder.
class User extends BaseModel
{
public function fullAgedScope($query)
{
return $query->where('age')->atLeast(18);
}
}
To use the newly created scope simply make a call that utilizes the scope method’s
name without the Scope
suffix.
// Return a list of full-aged users
$users = User::fullAged()
->orderBy('name')
->all();
Joins
All records returned by a query that uses joins
will be marked as read-only records.
A possible use case for joins is when you want, for example, to return a list with all users that have written at least one article.
$users = User::join('articles', function($join){
$join->on('users.id', 'articles.user_id');
})
->all();
The above example will return duplicates if a user have written multiple articles.
This can be solved by selecting only the distinct users with the help of the distinct
method.
$users = User::join('articles', function($join){
$join->on('users.id', 'articles.user_id');
})
->distinct()
->all();
Single column’s value
Retrieving a single column’s value is done by using the column
method.
The method returns the scalar value of the column or false
if no records were found.
$name = User::where('id')->is(1)->column('name');
Aggregates
You can also use all the aggregates functions. These methods return scalar values.
$count = User::count();
$max = User::max('age');
$avg = User::avg('age');
Inserting records
Inserting new records is done by creating a new instance of a model, setting the desired attributes
on the model’s instance and then calling the model’s save
method.
$user = new User;
$user->name = 'John Doe';
$user->email = 'foo@example.com';
$user->age = 18;
$user->save();
Updating records
Updating a model consists in retrieving the model, setting the properties you want to update,
and finally calling the save
method.
$user = User::find(1);
$user->email = 'bar@example.com';
$user->save();
You can also update models that match a given query by using the update
method.
User::where('id')->is(1)
->update(['is_active' => true]);
Read-only records
By default, the models retrieved using join clauses are marked as read-only.
Trying to save or to update a read-only model will result into an exception being thrown.
A model can also be explicitly marked as being read-only by setting the model’s
$readonly
property to true.
class Comment extends BaseModel
{
protectd $readonly = true;
}
Mass assignment
Another way of creating or updating models is through mass assignment.
Creating a model through mass assignment is done by using the create
method.
The method returns the instance of the inserted model.
$user = User::create(['name' => 'John Doe',
'email' => 'foo@example.com',
'age' => 18]);
Updating an existing model is done by using the assign
method on the model’s instance.
$user = User::find(1);
$user->assign(['email' => 'bar@example.com']);
$user->save();
Fillable attributes
You can define which properties of the model can be set through mass assignment
by using the $fillable
property. The property must contain an array with all
the column names that can receive values through mass assignment.
class User extends BaseModel
{
protected $fillable = ['name', 'email', 'age'];
}
Guarded attributes
Defining which properties of a model are not fillable is done by using the $guarded
property.
The property must contain an array with all the column names that can not receive
values through mass assignment.
The $guarded
attributes serve as a black list while
the $fillable
attributes serve as a white list. You should only use one of this two, not both.
class User extends BaseModel
{
protected $guarded = ['id', 'is_active', 'is_admin'];
}
Deleting records
Deleting a record form the database can be done by calling the delete
method on a model’s instance.
$user = User::find(1);
$user->delete();
You can also use a query if you want to select a set of models that needs to be deleted.
User::where('age')->lessThan(18)
->delete();