模型转换器

介绍

访问器和转换器允许您在从模型中检索属性或设置其值时格式化属性。 例如,您可能希望使用加密服务 在存储在数据库中时对值进行加密,然后在模型上访问该属性时自动解密该属性。

除了自定义访问器和转换器之外,您还可以自动将日期字段转换为Carbon 实例,甚至将文本值转换为JSON

访问器和转换器

定义一个访问器

要定义访问器,请在模型上创建一个getFooAttribute方法,其中Foo是您要访问的列的“驼峰”名称。 在这个例子中,我们将为first_name属性定义一个访问器。 尝试检索first_name的值时,将自动调用访问器:

  1. <?php namespace Acme\Blog\Models;
  2. use Model;
  3. class User extends Model
  4. {
  5. /**
  6. * 获取用户的名
  7. *
  8. * @param string $value
  9. * @return string
  10. */
  11. public function getFirstNameAttribute($value)
  12. {
  13. return ucfirst($value);
  14. }
  15. }

如您所见,列的原始值将传递给访问器,允许您操作并返回值。 要访问访问器处理过的值,您可以只访问first_name属性:

  1. $user = User::find(1);
  2. $firstName = $user->first_name;

定义一个转换器

要定义一个转换器,请在模型上定义一个setFooAttribute方法,其中Foo是您要访问的列的“驼峰”名称。 在这个例子中,让我们为first_name属性定义一个转换器。 当我们尝试在模型上设置first_name属性的值时,将自动调用此转换器:

  1. <?php namespace Acme\Blog\Models;
  2. use Model;
  3. class User extends Model
  4. {
  5. /**
  6. * 设置用户的名
  7. *
  8. * @param string $value
  9. * @return string
  10. */
  11. public function setFirstNameAttribute($value)
  12. {
  13. $this->attributes['first_name'] = strtolower($value);
  14. }
  15. }

转换器将接收在属性上设置的值,允许您操作该值并在模型的内部$attributes属性上设置操纵值。 例如,如果我们尝试将first_name属性设置为Sally

  1. $user = User::find(1);
  2. $user->first_name = 'Sally';

这里将使用值Sally调用setFirstNameAttribute函数。 然后,转换器将strtolower函数应用于name,并在内部$attributes数组中设置其值。

日期转换器

默认情况下,October的模型会将created_atupdated_at列转换为Carbon对象的实例,该对象提供各种有用的方法并扩展原生PHPDateTime类。

您可以通过覆盖模型的$dates属性来自定义哪些字段会自动转换,甚至完全禁用此转换:

  1. class User extends Model
  2. {
  3. /**
  4. * 应该转换为日期的属性。
  5. *
  6. * @var array
  7. */
  8. protected $dates = ['created_at', 'updated_at', 'disabled_at'];
  9. }

当列被视为日期时,您可以将其值设置为UNIX时间戳,日期字符串(Ymd),日期时间字符串,当然还有DateTime/Carbon实例,日期值将自动 正确存储在您的数据库中:

  1. $user = User::find(1);
  2. $user->disabled_at = Carbon::now();
  3. $user->save();

如上所述,当检索$dates属性中列出的属性时,它们将自动转换为Carbon 实例,允许您使用任何Carbon的方法 在你的属性上:

  1. $user = User::find(1);
  2. return $user->disabled_at->getTimestamp();

默认情况下,时间戳格式为“Y-m-d H:i:s”。 如果需要自定义时间戳格式,请在模型上设置$dateFormat属性。 此属性确定数据库中日期属性的存储方式,以及将模型序列化为数组或JSON时的格式:

  1. class Flight extends Model
  2. {
  3. /**
  4. * 模型日期列的存储格式。
  5. *
  6. * @var string
  7. */
  8. protected $dateFormat = 'U';
  9. }

属性转换

模型上的$casts属性提供了将属性转换为常见数据类型的便捷方法。 $casts属性应该是一个数组,其中键是要转换的属性的名称,而值是您希望转换为列的类型。 支持的强制类型是:integerrealfloatdoublestringbooleanobjectarray

例如,让我们将is_admin属性转换为一个布尔值,该属性作为整数(01)存储在我们的数据库中:

  1. class User extends Model
  2. {
  3. /**
  4. * 需要转换为原生类型的属性。
  5. *
  6. * @var array
  7. */
  8. protected $casts = [
  9. 'is_admin' => 'boolean',
  10. ];
  11. }

现在,当您访问它时,is_admin属性将始终强制转换为布尔值,即使基础值作为整数存储在数据库中:

  1. $user = User::find(1);
  2. if ($user->is_admin) {
  3. //
  4. }

数组转换

在处理存储为序列化JSON的列时,array强制转换类型特别有用。 例如,如果您的数据库具有包含序列化JSON的TEXT字段类型,则在您的Eloquent模型上访问该属性时,将“array”强制转换为该属性会自动将该属性反序列化为PHP数组:

  1. class User extends Model
  2. {
  3. /**
  4. * 需要转换为原生类型的属性。
  5. *
  6. * @var array
  7. */
  8. protected $casts = [
  9. 'options' => 'array',
  10. ];
  11. }

定义了强制转换后,您可以访问options属性,它将自动从JSON反序列化为PHP数组。 设置options属性的值时,给定的数组将自动序列化为JSON以进行存储:

  1. $user = User::find(1);
  2. $options = $user->options;
  3. $options['key'] = 'value';
  4. $user->options = $options;
  5. $user->save();