# Eloquent ORM —— 訪問器&修改器
## 1、簡介
訪問器屬性。例如,你可能想要使用[Laravel加密器](http://laravelacademy.org/post/189.html)對存儲在數據庫中的數據進行加密,并且在Eloquent模型中訪問時自動進行解密。
除了自定義訪問器和修改器,Eloquent還可以自動轉換日期字段為[Carbon](https://github.com/briannesbitt/Carbon)實例甚至[將文本轉換為JSON](http://laravelacademy.org/post/146.html#attribute-casting)。
## 2、訪問器 & 修改器
### 2.1 定義訪問器
要定義一個訪問器,需要在模型中創建一個`getFooAttribute`方法,其中`Foo`是你想要訪問的字段名(使用駝峰式命名規則)。在本例中,我們將會為`first_name`屬性定義一個訪問器,該訪問器在獲取`first_name`的值時被Eloquent自動調用:
~~~
<?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;
~~~
### 2.2 定義修改器
要定義一個修改器,需要在模型中定義`setFooAttribute`方法,其中`Foo`是你想要訪問的字段(使用駝峰式命名規則)。接下來讓我們為`first_name`屬性定義一個修改器,當我們為模型上的`first_name`賦值時該修改器會被自動調用:
~~~
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model{
/**
* 設置用戶的名字
*
* @param string $value
* @return string
*/
public function setFirstNameAttribute($value)
{
$this->attributes['first_name'] = strtolower($value);
}
}
~~~
該修改器獲取要被設置的屬性值,允許你操縱該值并設置Eloquent模型內部屬性值為操作后的值。例如,如果你嘗試設置`Sally`的`first_name`屬性:
~~~
$user = App\User::find(1);
$user->first_name = 'Sally';
~~~
在本例中,`setFirstNameAttribute`方法會被調用,傳入參數為`Sally`,修改器會對其調用`strtolower`函數并將處理后的值設置為內部屬性的值。
## 3、日期修改器
默認情況下,Eloquent將會轉化`created_at`和`updated_at`列的值為[Carbon](https://github.com/briannesbitt/Carbon)實例,該類繼承自PHP原生的`Datetime`類,并提供了各種有用的方法。
你可以自定義哪些字段被自動調整修改,甚至可以通過重寫模型中的`$dates`屬性完全禁止調整:
~~~
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model{
/**
* 應該被調整為日期的屬性
*
* @var array
*/
protected $dates = ['created_at', 'updated_at', 'disabled_at'];
}
~~~
如果字段是日期格式時,你可以將其值設置為UNIX時間戳,日期字符串(`Y-m-d`),日期-時間字符串,`Datetime/Carbon`實例,日期的值將會自動以正確格式存儲到數據庫中:
~~~
$user = App\User::find(1);
$user->disabled_at = Carbon::now();
$user->save();
~~~
正如上面提到的,當獲取被羅列在`$dates`數組中的屬性時,它們會被自動轉化為`Carbon`實例,允許你在屬性上使用任何`Carbon`的方法:
~~~
$user = App\User::find(1);
return $user->disabled_at->getTimestamp();
~~~
如果你需要自定義時間戳格式,在模型中設置`$dateFormat`屬性,該屬性決定日期屬性將以何種格式存儲在數據庫中、以及序列化為數組或JSON時的格式:
~~~
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model{
/**
* 模型日期的存儲格式
*
* @var string
*/
protected $dateFormat = 'U';
}
~~~
## 4、屬性轉換
模型中的`$casts`屬性提供了便利方法轉換屬性到通用數據類型。`$casts`屬性是數組格式,其鍵是要被轉換的屬性名稱,其值時你想要轉換的類型。目前支持的轉換類型包括:`integer`,?`real`,?`float`,?`double`,?`string`,?`boolean`,?`object`和`array`。
例如,讓我們轉換`is_admin`屬性,將其由`integer`類型轉換為`boolean`類型:
~~~
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model{
/**
* 應該被轉化為原生類型的屬性
*
* @var array
*/
protected $casts = [
'is_admin' => 'boolean',
];
}
~~~
現在,`is_admin`屬性在被訪問時總是被轉換為`boolean`,即使底層存儲在數據庫中的值是`integer`:
~~~
$user = App\User::find(1);
if ($user->is_admin) {
//
}
~~~
### 4.1 數組轉換
`array`類型轉換在處理被存儲為序列化JSON的字段是特別有用,例如,如果數據庫有一個TEXT字段類型包含了序列化JSON,添加`array`類型轉換到該屬性將會在Eloquent模型中訪問其值時自動將其反序列化為PHP數組:
~~~
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model{
/**
* 應該被轉化為原生類型的屬性
*
* @var array
*/
protected $casts = [
'options' => 'array',
];
}
~~~
類型轉換被定義后,就可以訪問`options`屬性,它將會自動從JSON反序列化為PHP數組,當你設置`options`屬性的值時,給定數組將會自動轉化為JSON以供存儲:
~~~
$user = App\User::find(1);
$options = $user->options;
$options['key'] = 'value';
$user->options = $options;
$user->save();
~~~
- 前言
- 序言
- 序言 ―― 發行版本說明
- 序言 ―― 升級指南
- 序言 ―― 貢獻代碼
- 開始
- 開始 ―― 安裝及配置
- 開始 ―― Laravel Homestead
- 基礎
- 基礎 ―― HTTP路由
- 基礎 ―― HTTP 中間件
- 基礎 ―― HTTP 控制器
- 基礎 ―― HTTP 請求
- 基礎 ―― HTTP 響應
- 基礎 ―― 視圖
- 基礎 ―― Blade模板
- 架構
- 架構 ―― 一次請求的生命周期
- 架構 ―― 應用目錄結構
- 架構 ―― 服務提供者
- 架構 ―― 服務容器
- 架構 ―― 契約
- 架構 ―― 門面
- 數據庫
- 數據庫 ―― 起步
- 數據庫 ―― 查詢構建器
- 數據庫 ―― 遷移
- 數據庫 ―― 填充數據
- Eloquent ORM
- Eloquent ORM ―― 起步
- Eloquent ORM ―― 關聯關系
- Eloquent ORM ―― 集合
- Eloquent ORM ―― 調整器
- Eloquent ORM ―― 序列化
- 服務
- 服務 ―― 用戶認證
- 服務 ―― Artisan 控制臺
- 服務 ―― Laravel Cashier(交易)
- 服務 ―― 緩存
- 服務 ―― 集合
- 服務 ―― Laravel Elixir
- 服務 ―― 加密
- 服務 ―― 錯誤&日志
- 服務 ―― 事件
- 服務 ―― 文件系統/云存儲
- 服務 ―― 哈希
- 服務 ―― 幫助函數
- 服務 ―― 本地化
- 服務 ―― 郵件
- 服務 ―― 包開發
- 服務 ―― 分頁
- 服務 ―― 隊列
- 服務 ―― Redis
- 服務 ―― Session
- 服務 ―― Envoy 任務運行器(SSH任務)
- 服務 ―― 任務調度
- 服務 ―― 測試
- 服務 ―― 驗證