在验证前后需要对数据进行一些处理,比如:格式化数值,设置默认值等,验证完毕后对数据进行加密,解密,格式化等操作,这时候就可以使用数据处理器来实现。
使用
通过类属性
为验证器定义前置处理器的属性为 $preprocessor
,定义后置处理器的属性为 $postprocessor
。
以下是一个简单的示例:
use Itwmw\Validate\Support\Processor\ProcessorExecCond;
use Itwmw\Validate\Support\Processor\ProcessorOptions;
use Itwmw\Validate\Support\Processor\ProcessorParams;
use Itwmw\Validate\Validate;
class Test extends Validate
{
protected $rule = [
'name' => 'nullable|string',
];
protected $preprocessor = [
'name' => ['默认名称', ProcessorExecCond::WHEN_EMPTY]
];
protected $postprocessor = [
'name' => ['trim', ProcessorParams::Value]
];
}
以上代码的含义为:在验证之前,当 name
字段为空时,将其设置为默认名称
,当验证完毕后,将 name
字段的值进行 trim 操作,并传递验证值作为参数。关于可选参数, 可以查看数据处理器的参数
执行时机
处理器默认任何时候都会执行,如果不想执行,可以使用ProcessorExecCond::WHEN_NOT_EMPTY
或ProcessorExecCond::WHEN_EMPTY
来指定执行时机。
使用多个处理器
可以通过为给处理器提供一个ProcessorOptions::MULTIPLE
来声明定义多个处理器,如:
use Itwmw\Validate\Support\Processor\ProcessorExecCond;
use Itwmw\Validate\Support\Processor\ProcessorOptions;
use Itwmw\Validate\Support\Processor\ProcessorParams;
use Itwmw\Validate\Validate;
class Test extends Validate
{
protected $rule = [
'name' => 'nullable|string',
];
protected $preprocessor = [
'name' => [
ProcessorOptions::MULTIPLE,
['默认名称', ProcessorExecCond::WHEN_EMPTY],
['trim', ProcessorParams::Value],
]
];
}
以上代码的含义为:使用 ProcessorOptions::MULTIPLE
声明,定义了多个处理器, 在验证之前,当 name
字段为空时,将其设置为默认名称
,然后将 name
字段的值进行 trim 操作,并传递验证值作为参数。
通过验证场景
如需在验证场景中使用数据处理器,可以需要验证场景类的 preprocessor 和 postprocessor 方法,如:
class Test extends Validate
{
protected $rule = [
'name' => 'nullable|string',
];
protected function sceneSave(ValidateScene $scene): void
{
$scene->only(true)
->preprocessor('name', '默认名称', ProcessorExecCond::WHEN_EMPTY)
->postprocessor('name', 'trim', ProcessorParams::Value);
}
}
$data = Test::make()->scene('save')->check([]);
var_dump($data);
//array(1) {
// ["name"]=>
// string(12) "默认名称"
//}
$data = Test::make()->check([]);
var_dump($data);
//array(0) {
//}
在上述示例代码中,场景 save
中定义了一个前置处理器,当验证值为空时,将其设置为默认名称
, 并且定义了一个后置处理器,将 name
字段的值进行 trim 操作,并传递验证值作为参数。
定义
数据处理器支持以下几种定义方式:
- 直接使用标量
- 使用函数名称
- 使用当前类下的处理器方法名
- 实现了
ProcessorInterface
接口的类或者完整类名 - 在验证场景中使用闭包方法
闭包
在验证场景中,可以直接传递一个闭包作为处理器方法,如:
class Test extends Validate
{
protected $rule = [
'name' => 'nullable|string',
];
protected function sceneSave(ValidateScene $scene): void
{
$scene->only(true)
->preprocessor('name', function (mixed $value, string $attribute, array $data) {
if (empty($value)) {
return '默认名称';
}
return $value;
}, ProcessorParams::Value, ProcessorParams::Attribute, ProcessorParams::OriginalData);
}
}
$data = Test::make()->scene('save')->check([]);
var_dump($data);
//array(1) {
// ["name"]=>
// string(12) "默认名称"
//}
参数顺序
处理器获取的参数顺序和定义的参数顺序一致,如果需要获取其他参数,可以使用 ProcessorParams
中的常量来获取。
类方法
在当前类中定义一个方法,然后将方法名作为处理器,方法名的定义规则为:首字母小写的方法名 + Processor
,如:
class Test extends Validate
{
protected $rule = [
'name' => 'nullable|string',
];
protected $preprocessor = [
'name' => 'setDefaultName',
];
protected function setDefaultNameProcessor(mixed $value)
{
return empty($value) ? '默认名称' : $value;
}
}
$data = Test::make()->check([]);
var_dump($data);
//array(1) {
// ["name"]=>
// string(12) "默认名称"
//}
未指定参数
如果没有指定参数,那么默认按序传递 ProcessorParams::Value
, ProcessorParams::Attribute
, ProcessorParams::OriginalData
, ProcessorParams::DataAttribute
四个参数
处理器类
定义处理器类,需要实现 Itwmw\Validate\Support\Concerns\ProcessorInterface
接口,然后直接使用,无需指定参数。
定义一个处理器类:
class RemoveScriptProcessor implements ProcessorInterface
{
public function handle($value, string $attribute, array $originalData)
{
// 处理script demo,仅供展示
$value = preg_replace('/<script.*?>.*?<\/script>/si', '', $value);
return strip_tags($value);
}
}
使用处理器类:
class Test extends Validate
{
protected $rule = [
'name' => 'nullable|string',
];
protected $postprocessor = [
'name' => RemoveScriptProcessor::class,
];
}
$data = Test::make()->check([
'name' => '<script>alert(1)</script>名称'
]);
var_dump($data);
//array(1) {
// ["name"]=>
// string(6) "名称"
//}
数据处理器的参数
多个ProcessorExecCond
可组合使用
ProcessorExecCond
为数据处理器的执行时机ProcessorOptions::WHEN_NOT_EMPTY
当字段不为空时执行ProcessorOptions::WHEN_EMPTY
当字段为空时执行ProcessorOptions::WHEN_NOT_EXIST
当字段不存在时执行ProcessorOptions::WHEN_EXIST
当字段存在时执行ProcessorOptions::ALWAYS
总是执行,默认行为
ProcessorParams
为数据处理器的参数来源,有四个值ProcessorParams::Value
使用字段的值作为参数ProcessorParams::Attribute
使用字段的键作为参数ProcessorParams::OriginalData
使用原始数据作为参数ProcessorParams::DataAttribute
提供一个DataAttribute
类作为参数
ProcessorOptions
为数据处理器的可选参数,有两个值ProcessorOptions::MULTIPLE
为同一个字段添加多个处理器时使用ProcessorOptions::VALUE_IS_ARRAY
当值为一个数组时使用,添加此选项后,验证器会将除了ProcessorExecCond
以外的参数传入处理器中,如果不添加此选项,验证器会将第一个值作为参数传入处理器中