Eloquent:序列化
簡介
當使用 Laravel 建構 API 時,您通常需要將模型和關聯轉換為陣列或 JSON。Eloquent 包含方便的方法來進行這些轉換,以及控制哪些屬性包含在模型的序列化表示中。
對於處理 Eloquent 模型和集合 JSON 序列化的更強大方法,請查看有關 Eloquent API 資源的文件。
序列化模型和集合
序列化為陣列
要將模型及其載入的關聯轉換為陣列,您應該使用 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。您也可以指定 PHP 支援的任何 JSON 編碼選項
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 關聯方法是使用「駝峰式」方法名稱定義的,但關聯的 JSON 屬性將是「蛇形式」。
從 JSON 中隱藏屬性
有時您可能希望限制包含在模型陣列或 JSON 表示中的屬性,例如密碼。若要執行此操作,請將 $hidden
屬性新增至您的模型。在 $hidden
屬性的陣列中列出的屬性將不會包含在模型的序列化表示中
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; class User extends Model{ /** * The attributes that should be hidden for serialization. * * @var array<string> */ protected $hidden = ['password'];}
要隱藏關聯,請將關聯的方法名稱新增至 Eloquent 模型的 $hidden
屬性。
或者,您可以使用 visible
屬性來定義應包含在模型陣列和 JSON 表示中的屬性的「允許清單」。當模型轉換為陣列或 JSON 時,$visible
陣列中不存在的所有屬性都將被隱藏
<?php namespace App\Models; 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();
如果您希望暫時覆寫所有可見或隱藏的屬性,您可以使用 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
屬性。請注意,即使存取器的 PHP 方法是使用「駝峰式」定義的,屬性名稱通常也會使用其「蛇形式」序列化表示來參考
<?php namespace App\Models; 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();
日期序列化
自訂預設日期格式
您可以透過覆寫 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', ];}