Eloquent:修改器
简介
访问器和修改器允许您在获取或设置模型实例属性时格式化 Eloquent 属性值。例如,可能希望使用 Laravel 加密器 在将值存储到数据库时对其加密,然后在 Eloquent 模型上访问它时自动解密该属性。
除了自定义访问器和修改器外,Eloquent 还可以自动将日期字段转换为 Carbon 实例,或者甚至 将文本字段转换为 JSON。
访问器 & 修改器
定义访问器
要定义访问器,可以在模型上创建一个 getFooAttribute
方法,Foo
是希望访问的字段名的「首字母大写的驼峰命名法」。在此示例中,我们会为 first_name
属性定义一个访问器。当尝试获取 first_name
属性值时,Eloquent 会自动调用访问器:
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;
当然,也可以使用访问器从已有属性返回一个新的计算后的值:
/**
* 获取用户的全名
*
* @return string
*/
public function getFullNameAttribute()
{
return "{$this->first_name} {$this->last_name}";
}
如果要将这些计算后的值添加到模型的数组/JSON 形式中,需要追加它们。
定义修改器
要定义修改器,可以在模型上定义一个 setFooAttribute
方法,Foo
是希望访问的字段名的「首字母大写的驼峰命名法」。同样,我们为 first_name
属性定义一个修改器。当尝试在模型上设置 first_name
属性值时,此修改器会自动被调用:
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* 设置用户的名字
*
* @param string $value
* @return void
*/
public function setFirstNameAttribute($value)
{
$this->attributes['first_name'] = strtolower($value);
}
}
修改器会接收被设置到属性的值,允许您处理此值并将处理后的值设置在 Eloquent 模型内部的 $attributes
属性上。例如,如果我们尝试将 first_name
属性设置为 Sally
:
$user = App\User::find(1);
$user->first_name = 'Sally';
在此实例中,会使用 Sally
的值调用 setFirstNameAttribute
函数。然后,修改器将 strtolower
函数应用于名字并在内部的 $attributes
数组中设置其结果值。
日期转换器
默认情况下,Eloquent 会将 created_at
和 updated_at
字段转换为 Carbon 实例,此实例继承了 PHP 的 DateTime
类并提供各种有用的方法。通过覆盖模型的 $dates
属性,可以自定义要自动转换的日期,甚至完全禁用转换:
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* 要自定转换为日期的属性
*
* @var array
*/
protected $dates = [
'created_at',
'updated_at',
'deleted_at'
];
}
当字段是日期时,可以将其值设置为一个 UNIX 时间戳,日期字符串(Y-m-d
),日期时间字符串,当然还可以设置成 DateTime
/ Carbon
实例,日期值会自动正确地存储到数据库中:
$user = App\User::find(1);
$user->deleted_at = now();
$user->save();
如上所述,当获取列在 $dates
属性中的属性时,它们会自动被转换为 Carbon 实例,允许您在属性上使用任何 Carbon 的方法:
$user = App\User::find(1);
return $user->deleted_at->getTimestamp();
日期格式
默认情况下,时间戳会被格式化为 'Y-m-d H:i:s'
。如果需要自定义时间戳格式,可以在模型上设置 $dateFormat
属性。此属性决定了日期属性会怎样存储到数据库中,以及它们在模型被序列化为数组或 JSON 时的格式:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model
{
/**
* 模型的日期字段的存储格式
*
* @var string
*/
protected $dateFormat = 'U';
}
属性转换
模型上的 $casts
属性为将属性转换为常见数据类型提供了便捷的方法。$casts
属性应该是一个数组,数组的键是要转换的属性名,数组的值是希望字段转换的类型。支持的转换类型有:integer
,real
,float
,double
,string
,boolean
,object
,array
,collection
,date
,datetime
和 timestamp
。
例如,我们将在数据库中以整数(0
或 1
)存储的 is_admin
属性转换为一个布尔值:
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* 属性应该被转换的默认类型
*
* @var array
*/
protected $casts = [
'is_admin' => 'boolean',
];
}
现在当访问 is_admin
属性时,它将始终被转换为一个布尔值,即使在底层数据库存储的实际值是一个整数:
$user = App\User::find(1);
if ($user->is_admin) {
//
}
数组 & JSON 转换
当字段存储序列化的 JSON 时,array
转换类型尤其有用。例如,如果数据库有一个包含序列化 JSON 数据的 JSON
或 TEXT
类型的字段,为此字段添加 array
转换类型,当在 Eloquent 模型上访问该属性时,会自动将其反序列化为 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();
日期转换
使用 date
或 datetime
转换类型时,可以指定日期的格式。此格式会在 模型被序列化为数组或 JSON 时使用:
/**
* 属性应该被转换的默认类型
*
* @var array
*/
protected $casts = [
'created_at' => 'datetime:Y-m-d',
];