1. 程式人生 > >Laravel 5.5 Eloquent ORM - 模型資料轉化

Laravel 5.5 Eloquent ORM - 模型資料轉化

簡介

當構建 JSON API 時,經常需要轉化模型和關聯關係為陣列或 JSON。

Eloquent 提供了便捷方法以便實現這些轉換,還可以控制哪些屬性被包含到序列化中。

轉化為陣列

想要轉化模型及其載入的關聯關係為陣列,可以使用 toArray 方法。

toArray 方法是遞迴的,所有屬性及其關聯物件屬性(包括關聯的關聯)都會被轉化為陣列。

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

還可以轉化整個模型集合為陣列:

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

轉化為 JSON

要轉化模型為 JSON,可以使用 toJson 方法,toJson 方法也是遞迴的,所有屬性及其關聯屬性都會被轉化為 JSON。

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

你還可以轉化模型或集合為字串,這將會自動呼叫 toJson 方法:

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

由於模型和集合在轉化為字串的時候會被轉化為 JSON,你可以從應用的路由或控制器中直接返回 Eloquent 物件:

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

在 JSON 中隱藏屬性

有時候你希望在模型陣列或 JSON 顯示中隱藏某些屬性,比如密碼,要實現這個功能,在定義模型的時候設定 $hidden 屬性:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * 在陣列中隱藏的屬性
     *
     * @var array
     */
    protected $hidden = ['password'];
}

注:如果要隱藏關聯關係,可使用關聯關係的方法名,而不是動態屬性名。

此外,可以使用 $visible 屬性來定義模型陣列和 JSON 顯示的屬性白名單:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * 在陣列中顯示的屬性
     *
     * @var array
     */
    protected $visible = ['first_name', 'last_name'];
}

臨時暴露隱藏屬性

如果你想要在特定模型中臨時顯示隱藏的屬性,可以使用 makeVisible 方法,該方法以方法鏈的呼叫方式返回模型例項:

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

類似的,如果你想要隱藏給定模型例項上某些顯示的屬性,可以使用 makeHidden 方法:

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

追加值到 JSON

有時候,需要新增資料庫中沒有的欄位到陣列中,要實現這個功能,首先要為這個值定義一個訪問器:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * 為使用者獲取管理員標識
     *
     * @return bool
     */
    public function getIsAdminAttribute()
    {
        return $this->attributes['admin'] == 'yes';
    }
}

定義好訪問器後,新增欄位名到該模型的 appends 屬性。需要注意的是,儘管訪問器使用“camel case”形式定義,屬性名通常以“snake case”的方式被引用:

<?php

namespace App;

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();

日期序列化

Laravel 擴充套件了 Carbon 日期庫以便為 Carbon 的 JSON 序列化格式提供方便的定製化,要自定義所有 Carbon 日期在整個應用中如何被序列化,可以使用 Carbon::serializeUsing 方法。serializeUsing 方法接收一個閉包,該閉包返回字串形式的日期用於 JSON 序列化:

<?php

namespace App\Providers;

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

class AppServiceProvider extends ServiceProvider
{
    /**
     * Perform post-registration booting of services.
     *
     * @return void
     */
    public function boot()
    {
        Carbon::serializeUsing(function ($carbon) {
            return $carbon->format('U');
        });
    }

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