訪問器和調(diào)整器允許你在獲取模型屬性或設(shè)置其值時格式化 Eloquent 屬性。例如,你可能想要使用 Laravel 加密器對存儲在數(shù)據(jù)庫中的數(shù)據(jù)進行加密,并且在 Eloquent 模型中訪問時自動進行解密。
除了自定義訪問器和調(diào)整器,Eloquent 還可以自動轉(zhuǎn)換日期字段為 Carbon 實例甚至將文本轉(zhuǎn)換為 JSON。
要定義一個訪問器,需要在模型中創(chuàng)建一個getFooAttribute
方法,其中 Foo
是你想要訪問的字段名(使用駝峰式命名規(guī)則)。在本例中,我們將會為first_name
屬性定義一個訪問器,該訪問器在獲取 first_name
的值時被 Eloquent 自動調(diào)用:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model{
/**
* 獲取用戶的名字
*
* @param string $value
* @return string
*/
public function getFirstNameAttribute($value)
{
return ucfirst($value);
}
}
正如你所看到的,該字段的原生值被傳遞給訪問器,然后返回處理過的值。要訪問該值只需要簡單訪問 first_name
即可:
$user = App\User::find(1);
$firstName = $user->first_name;
要定義一個調(diào)整器,需要在模型中定義 setFooAttribute
方法,其中 Foo
是你想要訪問的字段(使用駝峰式命名規(guī)則)。接下來讓我們?yōu)?first_name
屬性定義一個調(diào)整器,當我們?yōu)槟P蜕系?first_name
賦值時該調(diào)整器會被自動調(diào)用:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model{
/**
* 設(shè)置用戶的名字
*
* @param string $value
* @return string
*/
public function setFirstNameAttribute($value)
{
$this->attributes['first_name'] = strtolower($value);
}
}
該調(diào)整器獲取要被設(shè)置的屬性值,允許你操縱該值并設(shè)置 Eloquent 模型內(nèi)部屬性值為操作后的值。例如,如果你嘗試設(shè)置 Sally
的 first_name
屬性:
$user = App\User::find(1);
$user->first_name = 'Sally';
在本例中,setFirstNameAttribute
方法會被調(diào)用,傳入?yún)?shù)為 Sally
,調(diào)整器會對其調(diào)用 strtolower
函數(shù)并將處理后的值設(shè)置為內(nèi)部屬性的值。
默認情況下,Eloquent 將會轉(zhuǎn)化 created_at
和 updated_at
列的值為 Carbon 實例,該類繼承自 PHP 原生的 Datetime
類,并提供了各種有用的方法。
你可以自定義哪些字段被自動調(diào)整修改,甚至可以通過重寫模型中的$dates
屬性完全禁止調(diào)整:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model{
/**
* 應(yīng)該被調(diào)整為日期的屬性
*
* @var array
*/
protected $dates = ['created_at', 'updated_at', 'disabled_at'];
}
如果字段是日期格式時,你可以將其值設(shè)置為 UNIX 時間戳,日期字符串(Y-m-d
),日期-時間字符串,Datetime/Carbon
實例,日期的值將會自動以正確格式存儲到數(shù)據(jù)庫中:
$user = App\User::find(1);
$user->disabled_at = Carbon::now();
$user->save();
正如上面提到的,當獲取被羅列在$dates
數(shù)組中的屬性時,它們會被自動轉(zhuǎn)化為 Carbon
實例,允許你在屬性上使用任何Carbon
的方法:
$user = App\User::find(1);
return $user->disabled_at->getTimestamp();
如果你需要自定義時間戳格式,在模型中設(shè)置$dateFormat
屬性,該屬性決定日期屬性將以何種格式存儲在數(shù)據(jù)庫中、以及序列化為數(shù)組或 JSON 時的格式:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model{
/**
* 模型日期的存儲格式
*
* @var string
*/
protected $dateFormat = 'U';
}
模型中的$casts
屬性提供了便利方法轉(zhuǎn)換屬性到通用數(shù)據(jù)類型。$casts
屬性是數(shù)組格式,其鍵是要被轉(zhuǎn)換的屬性名稱,其值時你想要轉(zhuǎn)換的類型。目前支持的轉(zhuǎn)換類型包括:integer
, real
, float
, double
, string
, boolean
, object
和 array
。
例如,讓我們轉(zhuǎn)換 is_admin
屬性,將其由 integer
類型轉(zhuǎn)換為 boolean
類型:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model{
/**
* 應(yīng)該被轉(zhuǎn)化為原生類型的屬性
*
* @var array
*/
protected $casts = [
'is_admin' => 'boolean',
];
}
現(xiàn)在,is_admin
屬性在被訪問時總是被轉(zhuǎn)換為 boolean
,即使底層存儲在數(shù)據(jù)庫中的值是 integer
:
$user = App\User::find(1);
if ($user->is_admin) {
//
}
array
類型轉(zhuǎn)換在處理被存儲為序列化 JSON 的字段是特別有用,例如,如果數(shù)據(jù)庫有一個 TEXT 字段類型包含了序列化 JSON,添加 array
類型轉(zhuǎn)換到該屬性將會在 Eloquent 模型中訪問其值時自動將其反序列化為 PHP 數(shù)組:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model{
/**
* 應(yīng)該被轉(zhuǎn)化為原生類型的屬性
*
* @var array
*/
protected $casts = [
'options' => 'array',
];
}
類型轉(zhuǎn)換被定義后,就可以訪問 options
屬性,它將會自動從 JSON 反序列化為 PHP 數(shù)組,當你設(shè)置options
屬性的值時,給定數(shù)組將會自動轉(zhuǎn)化為 JSON 以供存儲:
$user = App\User::find(1);
$options = $user->options;
$options['key'] = 'value';
$user->options = $options;
$user->save();