- Введение
- Сериализация моделей и коллекций
- Скрытие атрибутов из JSON
- Добавление значений в JSON
- Сериализация дат
#Введение
При создании API с использованием Laravel часто требуется преобразовывать модели и их связи в массивы или JSON. Eloquent предоставляет удобные методы для таких преобразований, а также для управления тем, какие атрибуты включаются в сериализованное представление моделей.
Для более продвинутого способа работы с JSON-сериализацией моделей и коллекций Eloquent ознакомьтесь с документацией по Eloquent API resources.
#Сериализация моделей и коллекций
#Сериализация в массивы
Чтобы преобразовать модель и её загруженные связи в массив, используйте метод 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',
];