1. Eloquent ORM
  2. Eloquent: Сериализация

Введение

При построении API с использованием Laravel вам часто приходится преобразовывать ваши модели и отношения в массивы или JSON. Eloquent включает удобные методы для выполнения этих преобразований, а также управления тем, какие атрибуты включаются в сериализованное представление ваших моделей.

Примечание Для более надежной обработки сериализации JSON моделей и коллекций Eloquent, ознакомьтесь с документацией по ресурсам API Eloquent.

Сериализация моделей и коллекций

Сериализация в массивы

Для преобразования модели и ее загруженных отношений в массив вы должны использовать метод toArray. Этот метод рекурсивен, поэтому все атрибуты и все отношения (включая отношения отношений) будут преобразованы в массивы:

use App\Models\User;
 
$user = User::with('roles')->first();
 
return $user->toArray();

Метод attributesToArray можно использовать для преобразования атрибутов модели в массив, но не ее отношений:

$user = User::first();
 
return $user->attributesToArray();

Вы также можете преобразовывать целые коллекции моделей в массивы, вызвав метод toArray на экземпляре коллекции:

$users = User::all();
 
return $users->toArray();

Сериализация в JSON

Для преобразования модели в JSON вы должны использовать метод toJson. Как и toArray, метод toJson рекурсивен, поэтому все атрибуты и отношения будут преобразованы в JSON. Вы также можете указать любые параметры кодирования JSON, которые поддерживаются PHP:

use App\Models\User;
 
$user = User::find(1);
 
return $user->toJson();
 
return $user->toJson(JSON_PRETTY_PRINT);

В качестве альтернативы вы можете привести модель или коллекцию к строке, что автоматически вызовет метод toJson на модели или коллекции:

return (string) User::find(1);

Поскольку модели и коллекции преобразуются в JSON при приведении к строке, вы можете возвращать объекты Eloquent непосредственно из маршрутов или контроллеров вашего приложения. Laravel автоматически сериализует ваши объекты Eloquent в JSON при их возврате из маршрутов или контроллеров:

Route::get('users', function () {
return User::all();
});

Отношения

Когда модель Eloquent преобразуется в JSON, ее загруженные отношения автоматически включаются в виде атрибутов в объект JSON. Кроме того, хотя методы отношений Eloquent определены с использованием имен "camel case", атрибут JSON отношения будет "snake case".

Скрытие атрибутов из JSON

Иногда вам может потребоваться ограничить атрибуты, такие как пароли, которые включаются в массив или JSON-представление вашей модели. Для этого добавьте свойство $hidden к вашей модели. Атрибуты, перечисленные в массиве свойства $hidden, не будут включены в сериализованное представление вашей модели:

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
 
class User extends Model
{
/**
* Атрибуты, которые должны быть скрытыми в массивах.
*
* @var array
*/
protected $hidden = ['password'];
}

Примечание Чтобы скрыть отношения, добавьте имя метода отношения в свойство $hidden модели Eloquent.

В качестве альтернативы вы можете использовать свойство visible для определения "списка разрешений" атрибутов, которые должны включаться в массив и JSON-представление вашей модели. Все атрибуты, отсутствующие в массиве $visible, будут скрыты, когда модель преобразуется в массив или JSON:

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
 
class User extends Model
{
/**
* Атрибуты, которые должны быть видимыми в массивах.
*
* @var array
*/
protected $visible = ['first_name', 'last_name'];
}

Временное изменение видимости атрибутов

Если вы хотите сделать некоторые обычно скрытые атрибуты видимыми для данного экземпляра модели, вы можете использовать метод makeVisible. Метод makeVisible возвращает экземпляр модели:

return $user->makeVisible('attribute')->toArray();

Аналогично, если вы хотите скрыть некоторые атрибуты, которые обычно видны, вы можете использовать метод makeHidden.

return $user->makeHidden('attribute')->toArray();

Если вы хотите временно переопределить все видимые или скрытые атрибуты, вы можете использовать методы setVisible и setHidden соответственно:

return $user->setVisible(['id', 'name'])->toArray();
 
return $user->setHidden(['email', 'password', 'remember_token'])->toArray();

Добавление значений в JSON

Иногда при преобразовании моделей в массивы или JSON может потребоваться добавить атрибуты, которые не имеют соответствующего столбца в вашей базе данных. Для этого сначала определите аксессор для значения:

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
 
class User extends Model
{
/**
* Определить, является ли пользователь администратором.
*/
protected function isAdmin(): Attribute
{
return new Attribute(
get: fn () => 'yes',
);
}
}

Если вы хотите, чтобы аксессор всегда добавлялся к массиву и JSON-представлению вашей модели, вы можете добавить имя атрибута в свойство appends вашей модели. Обратите внимание, что имена атрибутов обычно обозначаются с использованием их "snake case" сериализованного представления, хотя метод PHP аксессора определяется с использованием "camel case":

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
 
class User extends Model
{
/**
* Аксессоры, добавляемые в форму массива модели.
*
* @var array
*/
protected $appends = ['is_admin'];
}

После того как атрибут был добавлен в список appends, он будет включен как в массиве, так и в JSON-представлениях модели. Атрибуты в массиве appends также будут учитывать настройки visible и hidden, настроенные на модели.

Добавление значений во время выполнения

Во время выполнения вы можете указать экземпляру модели добавить дополнительные атрибуты, используя метод append. Или вы можете использовать метод setAppends для переопределения целого массива добавленных свойств для данного экземпляра модели:

return $user->append('is_admin')->toArray();
 
return $user->setAppends(['is_admin'])->toArray();

Сериализация дат

Настройка формата даты по умолчанию

Вы можете настроить формат сериализации по умолчанию, переопределив метод serializeDate. Этот метод не влияет на то, как ваши даты форматируются для хранения в базе данных:

/**
* Подготовить дату для массива / JSON-сериализации.
*/
protected function serializeDate(DateTimeInterface $date): string
{
return $date->format('Y-m-d');
}

Настройка формата даты для каждого атрибута

Вы можете настроить формат сериализации индивидуальных атрибутов дат Eloquent, указав формат даты в объявлениях приведения типов модели:

protected $casts = [
'birthday' => 'date:Y-m-d',
'joined_at' => 'datetime:Y-m-d H:00',
];