修改器
修改器
Eloquent: 修改器
簡(jiǎn)介
當(dāng)你在 Eloquent 模型實(shí)例中獲取或設(shè)置某些屬性值的時(shí)候,訪問(wèn)器和修改器允許你對(duì) Eloquent 屬性值進(jìn)行格式化。例如,你可能需要使用 Laravel 加密器 來(lái)加密保存在數(shù)據(jù)庫(kù)中的值,而在使用 Eloquent 模型訪問(wèn)該屬性的時(shí)候自動(dòng)進(jìn)行解密其值。
除了自定義訪問(wèn)器和修改器外,Eloquent 也會(huì)自動(dòng)將日期字段類型轉(zhuǎn)換為 Carbon 實(shí)例,或?qū)?文本類型轉(zhuǎn)換為 JSON。
訪問(wèn)器 & 修改器
定義一個(gè)訪問(wèn)器
若要定義一個(gè)訪問(wèn)器, 則需在模型上創(chuàng)建一個(gè) getFooAttribute
方法,要訪問(wèn)的 Foo
字段需使用「駝峰式」命名。 在這個(gè)示例中,我們將為 first_name
屬性定義一個(gè)訪問(wèn)器。當(dāng) Eloquent 嘗試獲取 first_name
屬性時(shí),將自動(dòng)調(diào)用此訪問(wèn)器:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model{ /** * 獲取用戶的姓名. * * @param string $value * @return string */ public function getFirstNameAttribute($value) { return ucfirst($value); } }
如你所見,字段的原始值被傳遞到訪問(wèn)器中,允許你對(duì)它進(jìn)行處理并返回結(jié)果。如果想獲取被修改后的值,你可以在模型實(shí)例上訪問(wèn) first_name
屬性:
$user = App\User::find(1); $firstName = $user->first_name;
當(dāng)然,你也可以通過(guò)已有的屬性值,使用訪問(wèn)器返回新的計(jì)算值:
/** * 獲取用戶的姓名. * * @return string */ public function getFullNameAttribute(){ return "{$this->first_name} {$this->last_name}"; }
{tip} 如果你需要將這些計(jì)算值添加到模型的數(shù)組 / JSON 中, 你需要追加它們.
定義一個(gè)修改器
若要定義一個(gè)修改器,則需在模型上面定義 setFooAttribute
方法。要訪問(wèn)的 Foo
字段使用「駝峰式」命名。讓我們?cè)賮?lái)定義一個(gè) first_name
屬性的修改器。當(dāng)我們嘗試在模式上在設(shè)置 first_name
屬性值時(shí),該修改器將被自動(dòng)調(diào)用:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model{ /** * 設(shè)置用戶的姓名. * * @param string $value * @return void */ public function setFirstNameAttribute($value) { $this->attributes['first_name'] = strtolower($value); } }
修改器會(huì)獲取屬性已經(jīng)被設(shè)置的值,允許你修改并且將其值設(shè)置到 Eloquent 模型內(nèi)部的 $attributes
屬性上。舉個(gè)例子,如果我們嘗試將 first_name
屬性的值設(shè)置為 Sally
:
$user = App\User::find(1); $user->first_name = 'Sally';
在這個(gè)例子中, setFirstNameAttribute
方法在調(diào)用的時(shí)候接受 Sally
這個(gè)值作為參數(shù)。接著修改器會(huì)應(yīng)用 strtolower
函數(shù)并將處理的結(jié)果設(shè)置到內(nèi)部的 $attributes
數(shù)組。
日期轉(zhuǎn)換器
默認(rèn)情況下,Eloquent 會(huì)將 created_at
和 updated_at
字段轉(zhuǎn)換為 Carbon 實(shí)例,它繼承了 PHP 原生的 DateTime
類并提供了各種有用的方法。你可以通過(guò)設(shè)置模型的 $dates
屬性來(lái)添加其他日期屬性:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model{ /** * 應(yīng)該轉(zhuǎn)換為日期格式的屬性. * * @var array */ protected $dates = [ 'seen_at', ]; }
{tip} 你可以通過(guò)將模型的公有屬性
$timestamps
值設(shè)置為false
來(lái)禁用默認(rèn)的created_at
和updated_at
時(shí)間戳。
當(dāng)某個(gè)字段是日期格式時(shí),你可以將值設(shè)置為一個(gè) UNIX 時(shí)間戳,日期時(shí)間 (Y-m-d
) 字符串,或者 DateTime
/ Carbon
實(shí)例。日期值會(huì)被正確格式化并保存到你的數(shù)據(jù)庫(kù)中:
$user = App\User::find(1); $user->deleted_at = now(); $user->save();
就如上面所說(shuō),當(dāng)獲取到的屬性包含在 $dates
屬性中時(shí),都會(huì)自動(dòng)轉(zhuǎn)換為 Carbon 實(shí)例,允許你在屬性上使用任意的 Carbon 方法:
$user = App\User::find(1); return $user->deleted_at->getTimestamp();
日期格式
默認(rèn)情況下,時(shí)間戳都將以 'Y-m-d H:i:s'
形式格式化。如果你需要自定義時(shí)間戳格式,可在模型中設(shè)置 $dateFormat
屬性。這個(gè)屬性決定了日期屬性將以何種形式保存在數(shù)據(jù)庫(kù)中,以及當(dāng)模型序列化成數(shù)組或 JSON 時(shí)的格式:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ /** * 模型日期字段的保存格式. * * @var string */ protected $dateFormat = 'U'; }
屬性類型轉(zhuǎn)換
模型中的 $casts
屬性提供了一個(gè)便利的方法來(lái)將屬性轉(zhuǎn)換為常見的數(shù)據(jù)類型。$casts
屬性應(yīng)是一個(gè)數(shù)組,且數(shù)組的鍵是那些需要被轉(zhuǎn)換的屬性名稱,值則是你希望轉(zhuǎn)換的數(shù)據(jù)類型。支持轉(zhuǎn)換的數(shù)據(jù)類型有: integer
, real
, float
,double
, decimal:<digits>
,string
, boolean
, object
, array
,collection
, date
, datetime
, 和 timestamp
。 當(dāng)需要轉(zhuǎn)換為 decimal
類型時(shí),你需要定義小數(shù)位的個(gè)數(shù),如: decimal:2
示例, 讓我們把以整數(shù)(0
或 1
)形式存儲(chǔ)在數(shù)據(jù)庫(kù)中的 is_admin
屬性轉(zhuǎn)成布爾值。
<?php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model { /** * 這個(gè)屬性應(yīng)該被轉(zhuǎn)換為原生類型. * * @var array */ protected $casts = [ 'is_admin' => 'boolean', ]; }
現(xiàn)在當(dāng)你訪問(wèn) is_admin
屬性時(shí),雖然保存在數(shù)據(jù)庫(kù)里的值是一個(gè)整數(shù)類型,但是返回值總是會(huì)被轉(zhuǎn)換成布爾值類型:
$user = App\User::find(1); if ($user->is_admin) { // }
數(shù)組 & JSON 轉(zhuǎn)換
當(dāng)你在數(shù)據(jù)庫(kù)存儲(chǔ)序列化的 JSON 的數(shù)據(jù)時(shí),array
類型的轉(zhuǎn)換非常有用。比如:如果你的數(shù)據(jù)庫(kù)具有被序列化為 JSON 的 JSON
或 TEXT
字段類型,并且在 Eloquent 模型中加入了 array
類型轉(zhuǎn)換,那么當(dāng)你訪問(wèn)的時(shí)候就會(huì)自動(dòng)被轉(zhuǎn)換為 PHP 數(shù)組。
<?php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model { /** * 這個(gè)屬性應(yīng)該被轉(zhuǎn)換為原生類型. * * @var array */ protected $casts = [ 'options' => 'array', ]; }
一旦定義了轉(zhuǎn)換,你訪問(wèn) options
屬性時(shí)他會(huì)自動(dòng)從 JSON 類型反序列化為 PHP 數(shù)組。當(dāng)你設(shè)置了 options
屬性的值時(shí),給定的數(shù)組也會(huì)自動(dòng)序列化為 JSON 類型存儲(chǔ):
$user = App\User::find(1); $options = $user->options; $options['key'] = 'value'; $user->options = $options; $user->save();
Date 轉(zhuǎn)換
當(dāng)使用 date
或 datetime
屬性時(shí),可以指定日期的格式。 這種格式會(huì)被用在 模型序列化為數(shù)組或者 JSON:
/** * 這個(gè)屬性應(yīng)該被轉(zhuǎn)化為原生類型. * * @var array */ protected $casts = [ 'created_at' => 'datetime:Y-m-d', ];