Eloquent: серіалізація
Вступ
Створюючи API на Laravel, ви часто перетворюватимете свої моделі та зв'язки на масиви чи JSON. Eloquent має для цього зручні методи, а також дозволяє керувати тим, які атрибути потрапляють до серіалізованого представлення ваших моделей.
Про ще потужніший спосіб серіалізувати моделі та колекції Eloquent у JSON читайте в документації з ресурсів 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\Attributes\Hidden;
use Illuminate\Database\Eloquent\Model;
#[Hidden(['password'])]
class User extends Model
{
// ...
}
Щоб приховати зв'язки, додайте назву методу зв'язку до атрибута
Hiddenвашої моделі Eloquent.
Або ж ви можете скористатися атрибутом Visible, щоб описати «білий список» атрибутів, які мають потрапляти до масиву та JSON-представлення моделі. Усі атрибути, яких немає в Visible, буде приховано при перетворенні моделі на масив чи JSON:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Visible;
use Illuminate\Database\Eloquent\Model;
#[Visible(['first_name', 'last_name'])]
class User extends Model
{
// ...
}
Тимчасова зміна видимості атрибутів
Якщо ви хочете зробити видимими на конкретному екземплярі моделі кілька зазвичай прихованих атрибутів, скористайтеся методами makeVisible чи mergeVisible. Метод makeVisible повертає екземпляр моделі:
return $user->makeVisible('attribute')->toArray();
return $user->mergeVisible(['name', 'email'])->toArray();
Так само, якщо ви хочете приховати кілька зазвичай видимих атрибутів, скористайтеся методами makeHidden чи mergeHidden:
return $user->makeHidden('attribute')->toArray();
return $user->mergeHidden(['name', 'email'])->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
{
/**
* Determine if the user is an administrator.
*/
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\Attributes\Appends;
use Illuminate\Database\Eloquent\Model;
#[Appends(['is_admin'])]
class User extends Model
{
// ...
}
Коли атрибут додано до списку appends, він потраплятиме і до масиву, і до JSON-представлення моделі. Атрибути з масиву appends також враховують налаштування visible та hidden вашої моделі.
Додавання під час виконання
Під час виконання ви можете наказати екземпляру моделі додати додаткові атрибути методами append чи mergeAppends. Або ж методом setAppends можна перевизначити цілий масив доданих властивостей для конкретного екземпляра моделі:
return $user->append('is_admin')->toArray();
return $user->mergeAppends(['is_admin', 'status'])->toArray();
return $user->setAppends(['is_admin'])->toArray();
Так само, якщо ви хочете прибрати з моделі всі додані властивості, скористайтеся методом withoutAppends:
return $user->withoutAppends()->toArray();
Серіалізація дат
Зміна формату дати за замовчуванням
Ви можете змінити формат серіалізації за замовчуванням, перевизначивши метод serializeDate. Цей метод не впливає на те, як ваші дати форматуються для зберігання в базі даних:
/**
* Prepare a date for array / JSON serialization.
*/
protected function serializeDate(DateTimeInterface $date): string
{
return $date->format('Y-m-d');
}
Зміна формату дати для окремого атрибута
Ви можете змінити формат серіалізації окремих атрибутів дати в Eloquent, задавши формат дати в оголошеннях приведення типів моделі:
protected function casts(): array
{
return [
'birthday' => 'date:Y-m-d',
'joined_at' => 'datetime:Y-m-d H:00',
];
}