Коли модель повертається з контролера чи перетворюється через toArray() / toJson(), у результат потрапляють усі атрибути з бази, а також завантажені зв'язки.
$hidden - атрибути, яких не має бути в масиві чи JSON:
class User extends Model
{
protected $hidden = ['password', 'remember_token', 'two_factor_secret'];
}
У Laravel 13 те саме можна записати атрибутом класу:
#[Hidden(['password', 'remember_token'])]
class User extends Model {}
$visible - навпаки, білий список: лише ці атрибути. Безпечніше, бо нова колонка в таблиці не з'явиться у відповіді автоматично.
$appends - додати обчислене значення з аксесора:
protected $appends = ['is_admin'];
protected function isAdmin(): Attribute
{
return Attribute::get(fn (): bool => $this->role === 'admin');
}
Без $appends аксесор працює в коді ($user->is_admin), але в JSON не потрапляє.
Тимчасово змінити видимість:
$user->makeVisible('email')->toArray();
$user->makeHidden('phone')->toArray();
$users->append('is_admin'); // для колекції
$user->setVisible(['id', 'name']);
Зв'язки: завантажені зв'язки серіалізуються разом з моделлю (ключ у snake_case). Щоб приховати зв'язок, його назву додають у $hidden.
Дати серіалізуються в ISO 8601 з UTC (2026-10-04T09:00:00.000000Z). Формат змінюють перевизначенням serializeDate() чи в касті: 'published_at' => 'datetime:Y-m-d'.
Підводні камені:
$appendsз аксесором, що звертається до зв'язку, дає N+1 при серіалізації колекції - кожна модель завантажує зв'язок окремо;$hidden- не захист: у коді атрибут доступний, і його можна вивести в шаблоні чи лог;- для API надійніше API Resources: формат описано явно, і він не залежить від того, які колонки є в таблиці.
Докладніше в документації: Серіалізація: приховування атрибутів