类型转换
数据转换器允许你在数据验证通过后,对指定字段进行类型转换。这在需要确保数据类型一致性时非常有用,例如,将来自请求的字符串数字转换为整数或浮点数。
使用方法
在你的 Validate
类中定义一个 protected $casts
属性。这个属性是一个数组,键是需要转换的字段名,值是目标类型。
class UserId
{
public function __construct(protected readonly int $id) {}
}
class TestValidate extends Validate
{
protected array $rule = [
'name' => 'required|string',
'age' => 'required|integer',
'id' => 'required|int|min:0',
];
protected array $casts = [
'age' => 'int',
'id' => UserId::class
];
}
当调用 check
方法时,age
字段将被转换为整数,id
字段将被转换为 UserId
对象。
$v = new TestValidate();
$data = $v->check([
'name' => 'John Doe',
'age' => '30',
'id' => 123
]);
// $data['age'] 的值将是 (int) 30
// $data['id'] 的值将是 UserIdCaster 的一个实例
内置类型
int
将值转换为整数 (integer
)。
protected $casts = ['age' => 'int'];
// '30' -> 30
float
将值转换为浮点数 (float
)。
protected $casts = ['price' => 'float'];
// '19.99' -> 19.99
decimal
将值转换为指定小数位数的浮点数。
protected $casts = [
'price' => 'decimal:2', // 保留两位小数
'rate' => 'decimal:4' // 保留四位小数
];
// '19.99' -> 19.99
// '0.12345' -> 0.1235
string
将值转换为字符串 (string
)。
protected $casts = ['zipcode' => 'string'];
// 12345 -> '12345'
bool
将值转换为布尔值 (boolean
)。'0'
, 0
, false
会被转换为 false
,其他值(包括字符串'false'
)会被转换为 true
。
protected $casts = ['is_active' => 'bool'];
// '1' -> true
// 0 -> false
array
将 JSON 字符串转换为 PHP 数组 (array
)。
protected $casts = ['options' => 'array'];
// '{"color":"red"}' -> ['color' => 'red']
object
将 JSON 字符串转换为 PHP stdClass
对象。
protected $casts = ['options' => 'object'];
// '{"color":"red"}' -> (object) ['color' => 'red']
json
将 PHP 数组或对象转换为 JSON 字符串。
protected $casts = ['properties' => 'json'];
// ['color' => 'red'] -> '{"color":"red"}'
json_unicode
将 PHP 数组或对象转换为经过 Unicode 转义的 JSON 字符串。
protected $casts = ['properties' => 'json_unicode'];
// ['name' => '墨娘'] -> '{"name":"\u58a8\u5a18"}'
collection
将数组或 JSON 字符串转换为 Itwmw\Validation\Support\Collection\Collection
对象。
protected $casts = ['users' => 'collection'];
枚举类
将值转换为指定的 PHP 枚举。
Backed Enum
示例
// enum ProductType: int { case BOOK = 1; ... }
protected $casts = ['product_type' => ProductType::class];
// 1 -> ProductType::BOOK
// 'BOOK' -> ProductType::BOOK
Pure Enum
示例
// enum LoginFrom { case PC; ... }
protected $casts = ['login_from' => LoginFrom::class];
// 'PC' -> LoginFrom::PC
自定义类
你可以将值转换为你自己的类对象。
简单类
如果你的类构造函数接受单个参数,你可以直接使用类名作为转换类型。
// class UserId { public function __construct(protected readonly int $id) {} }
protected $casts = ['user_id' => UserId::class];
// 123 -> new UserId(123)
转换类
为了更复杂的转换逻辑,你可以实现 Itwmw\Validate\Support\Concerns\ValidateCastable
接口。
use Itwmw\Validate\Support\Concerns\ValidateCastable;
class UserIdCaster extends UserId implements ValidateCastable
{
public static function castsAttributes(string $field, mixed $value, array $attributes): static
{
// 自定义转换逻辑
return new static($value);
}
}
// --- In Validate Class ---
protected $casts = ['user_id' => UserIdCaster::class];
数组
你可以在数组字段上使用转换器,包括使用 *
通配符。
class TestValidate extends Validate
{
protected $rule = [
'users' => 'array:@list',
'users.*' => 'array:name,id',
'users.*.name' => 'required|string',
'users.*.id' => 'required|int|min:0',
];
protected $casts = [
'users.*.id' => 'integer',
];
}
$data = $v->check([
'users' => [
['name' => 'Alice', 'id' => '1'],
['name' => 'Bob', 'id' => '2'],
]
]);
// $data['users'][0]['id'] will be (int) 1
// $data['users'][1]['id'] will be (int) 2
多重转换
你可以为一个字段应用多个转换器。它们将按顺序执行。
protected $casts = [
'options' => ['array', 'json_unicode']
];
// '[{"name":"虞灪"}]' -> (step 1: array) [['name' => '虞灪']] -> (step 2: json_unicode) '[{"name":"\u865e\u706a"}]'