Laravel 8 值对象类型转换
你不仅可以将数据转换成原生的数据类型,还可以将数据转换成对象。两种自定义类型转换的定义方式非常类似。但是将数据转换成对象的自定义转换类中的 set
方法需要返回键值对数组,用于设置原始、可存储的值到对应的模型中。
举个例子,定义一个自定义类型转换类用于将多个模型属性值转换成单个 Address
值对象,假设 Address
对象有两个公有属性 lineOne
和 lineTwo
:
<?php
namespace App\Casts;
use App\Models\Address;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use InvalidArgumentException;
class Address implements CastsAttributes
{
/**
* 将取出的数据进行转换
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param string $key
* @param mixed $value
* @param array $attributes
* @return \App\Models\Address
*/
public function get($model, $key, $value, $attributes)
{
return new Address(
$attributes['address_line_one'],
$attributes['address_line_two']
);
}
/**
* 转换成将要进行存储的值
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param string $key
* @param \App\Models\Address $value
* @param array $attributes
* @return array
*/
public function set($model, $key, $value, $attributes)
{
if (! $value instanceof Address) {
throw new InvalidArgumentException('The given value is not an Address instance.');
}
return [
'address_line_one' => $value->lineOne,
'address_line_two' => $value->lineTwo,
];
}
}
进行值对象类型转换后,任何对值对象的数据转换将会自动同步回模型中:
$user = App\Models\User::find(1);
$user->address->lineOne = 'Updated Address Value';
$user->save();
技巧:如果想将包含值对象的 Eloquent 模型序列化为 JSON 或数组,你只需让该模型实现
Illuminate\Contracts\Support\Arrayable
和JsonSerializable
接口即可。