# Eloquent: 修改器
- [简介](#introduction)
- [访问器 & 修改器](#accessors-and-mutators)
- [定义一个访问器](#defining-an-accessor)
- [定义一个修改器](#defining-a-mutator)
- [日期转换器](#date-mutators)
- [属性类型转换](#attribute-casting)
- [数组 & JSON 转换](#array-and-json-casting)
## 简介
当你在 Eloquent 模型实例中获取或设置某些属性值的时候,访问器和修改器允许你对 Eloquent 属性值进行格式化。例如,你可能想要使用 [Laravel 加密器](/docs/{{version}}/encryption) 来加密一个即将被保存在数据库中的值,而从 Eloquent 模型访问该属性时自动解密其值。
除了自定义访问器和修改器之外,Eloquent 也会自动将日期字段类型转换成 [Carbon](https://github.com/briannesbitt/Carbon) 实例或将 [文本字段类型转换成 JSON](#attribute-casting)。
## 访问器 & 修改器
### 定义一个访问器
若要定义一个访问器,则须在你的模型上创建一个 `getFooAttribute` 方法。要访问的 `Foo` 字段需使用「驼峰式」来命名。在这个例子中,我们将为 `first_name` 属性定义一个访问器。当 Eloquent 尝试获取 `first_name` 的值时,将会自动调用此访问器:
first_name;
当然,你也可以通过已有的属性,使用访问器返回新的计算值:
/**
* 获取用户姓名。
*
* @return string
*/
public function getFullNameAttribute()
{
return "{$this->first_name} {$this->last_name}";
}
### 定义一个修改器
若要定义一个修改器,则须在模型上定义一个 `setFooAttribute` 方法。要访问的 `Foo` 字段需使用「驼峰式」命名。让我们再来定义一个 `first_name` 属性的修改器。当我们尝试在模型上设置 `first_name` 的值时,该修改器将被自动调用:
attributes['first_name'] = strtolower($value);
}
}
修改器会获取属性已经被设置的值,允许你操作该值并将其设置到 Eloquent 模型内部的 `$attributes` 属性上。举个例子,如果我们尝试将 `first_name` 属性的值设置成 `Sally`:
$user = App\User::find(1);
$user->first_name = 'Sally';
在这个例子中, `setFirstNameAttribute` 方法在调用的时候会接收 `Sally` 这个值作为参数。接着修改器会应用 `strtolower` 函数并将处理结果的值设置到内部的 `$attributes` 数组。
## 日期转换器
默认情况下,Eloquent 会把 `created_at` 和 `updated_at` 字段转换成 [Carbon](https://github.com/briannesbitt/Carbon) 实例, 它继承了 PHP 原生的 `DateTime` 类,并提供了各种有用的方法。你可以通过重写模型的 `$dates` 属性,自行定义哪些日期类型字段会被自动转换,或者完全禁止所有日期类型字段的转换:
deleted_at = now();
$user->save();
就如上面所说的,当获取到的属性包含在 `$dates` 属性中时,都将会自动转换成 [Carbon](https://github.com/briannesbitt/Carbon) 实例,允许你在属性上使用任意的 `Carbon` 方法:
$user = App\User::find(1);
return $user->deleted_at->getTimestamp();
#### 日期格式
默认情况下,时间戳将会以 `'Y-m-d H:i:s'` 的形式格式化。如果你想要自定义时间戳格式,可在模型中设置 `$dateFormat` 属性。该属性决定了日期属性应以何种格式被保存到数据库中,以及当模型被序列化成数组 或 JSON 时的格式:
## 属性类型转换
模型中的 `$casts` 属性提供了一个便利的方法来将属性转换为常见的数据类型。`$casts` 属性应是一个数组,且数组的键是那些需要被转换的属性名称,值则是你希望转换的数据类型。支持转换的数据类型有: `integer` , `real` , `float` , `double` , `string` , `boolean` , `object` , `array` , `collection` , `date` , `datetime` 和 `timestamp`。
例如,让我们把以整数 ( `0` 或 `1` ) 形式存储在数据库中的 `is_admin` 属性转换成布尔值:
'boolean',
];
}
现在当你访问 `is_admin` 属性时,虽然保存在数据库里的的值是一个整数类型,但返回值总是会被转换成布尔值类型:
$user = App\User::find(1);
if ($user->is_admin) {
//
}
### 数组 & JSON 转换
当你在数据库存储系列化的 JSON 的数据时, `array` 类型转换非常有用. 例如, 如果你的数据库具有被序列化为JSON 的 `JSON` 或 `TEXT` 字段类型 ,并且在 Eloquent 模型中加入了 `array` 类型转换 ,那么当你访问的时候就会自动被转换为 PHP 数组:
'array',
];
}
一旦定义了转换, 你访问 `options` 属性时它会自动从 JSON 类型反序列化为 PHP 数组 。当你设置 `options` 属性的值时,给定的数组也会自动序列化为 JSON 类型存储:
$user = App\User::find(1);
$options = $user->options;
$options['key'] = 'value';
$user->options = $options;
$user->save();
### Date 转换
使用 `date` 或 `datetime` 转换类型时,你可以指定日期的格式。[当模型序列化为数组或JSON时](/docs/{{version}}/eloquent-serialization),将使用此格式:
/**
* 这个属性应该被转换为原生的类型.
*
* @var array
*/
protected $casts = [
'created_at' => 'datetime:Y-m-d',
];