[ Laravel 5.8 文件 ] Eloquent ORM —— 序列化
簡介
當構建 JSON API 時,經常需要轉化模型和關聯關係為陣列或 JSON。Eloquent 提供了便捷方法以便實現這些轉換,以及控制哪些屬性被包含到序列化中。
序列化模型 & 集合
序列化為陣列
要轉化模型及其載入的關聯關係為陣列,可以使用toArray
方法。這個方法是遞迴的,所以所有屬性及其關聯物件屬性(包括關聯的關聯)都會被轉化為陣列:
$user = App\User::with('roles')->first(); return $user->toArray();
還可以轉化整個模型集合為陣列:
$users = App\User::all(); return $users->toArray();
序列化為 JSON
要轉化模型為 JSON,可以使用toJson
方法,和toArray
一樣,toJson
方法也是遞迴的,所有屬性及其關聯屬性都會被轉化為 JSON。還可以指定PHP 支援的 JSON 編碼選項
:
$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(); });
在 JSON 中隱藏屬性
有時候你希望在模型陣列或 JSON 顯示中隱藏某些屬性,比如密碼,要實現這個功能,在定義模型的時候設定$hidden
屬性:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model { /** * 在陣列中隱藏的屬性 * * @var array */ protected $hidden = ['password']; }
注:如果要隱藏關聯關係,使用關聯關係的方法名,而不是動態屬性名。
此外,可以使用$visible
屬性來定義模型陣列和 JSON 顯示的屬性白名單。當模型被轉化為陣列或 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
有時候,轉化模型為陣列或 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();
日期序列化
自定義每個屬性的的日期格式
你可以通過指定轉化宣告中的日期格式來自定義單個 Eloquent 日期屬性的序列化格式:
protected $casts = [ 'birthday' => 'date:Y-m-d', 'joined_at' => 'datetime:Y-m-d H:00', ];
通過 Carbon 全域性自定義
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() { // } }