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

Содержание:


Введение

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


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

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

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

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

return $user->toArray();

Чтобы конвертировать атрибуты модели в массив, используйте метод attributesToArray:

$user = App\User::first();

return $user->attributesToArray();

Вы также можете конвертировать все коллекции моделей в массивы:

$users = App\User::all();

return $users->toArray();

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

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

$user = App\User::find(1);

return $user->toJson();

return $user->toJson(JSON_PRETTY_PRINT);

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

$user = App\User::find(1);

return (string) $user;

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

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

Связи

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


Спраятать атрибуты от JSON

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

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = ['password'];
}
При скрытии связи, используйте имя метода связи.

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

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * The attributes that should be visible in arrays.
     *
     * @var array
     */
    protected $visible = ['first_name', 'last_name'];
}

Настройка временной видимости атрибутов

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

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

По такой же схеме, вы можете сделать видимые атрибуты скрытыми для данного экземпляра модели. Для этого необходимо использовать метод makeHidden.

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

Добавление данных в JSON

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

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Get the administrator flag for the user.
     *
     * @return bool
     */
    public function getIsAdminAttribute()
    {
        return $this->attributes['admin'] === 'yes';
    }
}

После создания аксессора, добавьте имя атрибута в свойство appends для модели. Важно заметить, что имена атрибутов обыкновенно пишутся в "змеином_регистре", даже если аксессор определен с использованием "верблюжьегоРегистра":

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * The accessors to append to the model's array form.
     *
     * @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();

Сериализация времени

Настройка формата времени для атрибута

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

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

Глобальная настройка через Carbon

Ларавел расширяет библиотеку времени Carbon, чтобы обеспечить удобную настройку формата JSON сериализации. Чтобы настроить каким образом все даты карбон проходят сериализацию для всего приложения, используйте метод Carbon::serializeUsing . Метод serializeUsing принимает замыкание, которое возвращает строковое представление даты для JSON сериализации:

<?php

namespace App\Providers;

use Illuminate\Support\Carbon;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register bindings in the container.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Carbon::serializeUsing(function ($carbon) {
            return $carbon->format('U');
        });
    }
}