# 验证场景

规则管理器验证器均支持定义场景,验证不同场景的数据,例如:

class ArticleValidate extends Validate
{
    protected $rule = [
        'id'      => 'required|numeric',
        'content' => 'required|digits_between:1,2000',
        'title'   => 'required|digits_between:4,50|alpha',
    ];

    protected $message = [
        'id.required'            => '缺少参数:文章Id',
        'id.numeric'             => '参数错误:文章Id',
        'content.required'       => '文章内容必须填写',
        'content.digits_between' => '文章长度为1~2000个字符',
        'title.required'         => '文章标题必须填写',
        'title.digits_between'   => '文章标题格式错误',
        'title.alpha'            => '文章标题长度为4~50个字符',
    ];
    
    protected $scene = [
        'add'  => ['content','title'],
        'edit' => ['id','content','title'],
        'del'  => ['id'],
    ];
}

然后可以在验证方法中使用验证的场景,使用scene方法指定验证场景

$data = [
    'content' => '内容',
    'title'   => '这是一个标题'
];
$validate = new ArticleValidate();
$data     = $validate->scene('add')->check($data);

# 验证场景复用以及关联

如果两个验证场景中的字段要求都一样或想指定当前场景验证完继续验证下一个场景时,可以使用next关键词使用验证器

请注意

规则管理器不支持next关键词

# 场景复用

protected $scene = [
    'edit' => ['id','content','title'],
    'save' => ['next' => 'edit'],
];
$validate = new ArticleValidate();
$validate->scene('save')->check($data);

这里是save场景,实际上是用的edit场景字段

如都定义了中间件,则都生效

# 场景关联

当我们想一些字段符合要求后再继续验证另一些字段,或者场景的自由组合,就需要用到了场景关联:

class User extends Validate
{
    protected $rule = [
        'username' => 'required|alpha',
        'password' => 'required|alpha_num|min:6|max:16',
        'mobile'   => 'regex:/^1[3-9]\d{9}$/',
        'name'     => 'alpha|max:10',
        'age'      => 'numeric|min:1|max:150'
    ];

    protected $scene = [
        'register'      => ['username', 'password', 'mobile', 'next' => 'checkUserInfo'],
        'checkUserInfo' => ['name', 'age']
    ];
}

$data = User::make()->scene('register')->check([
    'username' => 'Melody',
    'password' => '123456',
    'mobile'   => '13122223333',
    'name'     => 'Melody',
    'age'      => '20'
]);

print_r($data);

以上代码首先会验证register场景,如果register中的字段全部验证通过后,继续验证checkUserInfo场景,最后得到全部验证通过的数据

Array
(
    [username] => Melody
    [password] => 123456
    [mobile] => 13122223333
    [name] => Melody
    [age] => 20
)

# 场景选择器

next关键词支持使用场景选择器.场景选择器的命名规则为:场景选择器名称 + Selector

protected $scene = [
    'save' => ['type','next' = 'saveType'],
    'saveSetting' => ['id','name']
]


protected function saveTypeSelector(array $data)
{
    return 'save'.$data['type'];
}

自定义方法的参数

自定义方法会有一个数组类型的参数,传入的参数为之前验证过的全部数据,返回字符串为使用对应的验证场景,返回数组为使用对应的验证字段

# 自定义验证场景

可以单独为某个场景定义方法(方法的命名规范是scene+ 首字母大写的场景名),方法提供一个场景类,可用于对某些字段的规则重新设置,例如:

  • 规则管理器中的场景类为:W7\Validate\Support\RuleManagerScene
  • 验证器中的场景类为:W7\Validate\Support\ValidateScene

注意

场景名在调用的时候不能将驼峰写法转为下划线

protected function sceneEdit($scene)
{
   $scene->only(['id','content','title'])
        ->append('id',"max")
        ->remove("content",'between')
        ->remove('title',null)
        ->append('title','required|between|alpha');
}

说明

scene验证场景在调用check方法以后会被重置,并不会对下一次check生效

# 验证字段为数组

在验证器中,支持对数组下的元素进行定义规则,在验证场景中,同样支持指定验证数组元素 规则的定义如下:

protected $rule = [
    'search.order'   => 'numeric|between:1,2',
    'search.keyword' => 'chsAlphaNum',
    'search.recycle' => 'boolean',
];

验证场景定义:

protected $scene = [
    'list'    =>  ['search.order','search.keyword','search.recycle']
];

# 场景类的方法

验证器的场景类方法说明如下:

方法名 描述
only 场景中需要验证的字段
remove 移除场景中的字段的部分验证规则
append 给场景中的字段追加验证规则
sometimes 复杂条件验证
event 指定事件处理类
getData 获取当前验证的数据
getValidateData 作用同getData,区别在于,此方法返回一个验证器集合
before 添加一个验证前的需要执行的方法
after 添加一个验证后需要执行的方法
appendCheckField 添加一个需要验证的字段
removeCheckField 删除一个需要验证的字段
setEventPriority 设置事件和简易事件的优先级
default 设置或取消一个字段的默认值
filter 设置或取消一个字段的过滤器
next 指定下一个场景或者场景选择器

规则管理器的场景类方法说明如下:

方法名 描述
only 场景中需要验证的字段
remove 移除场景中的字段的部分验证规则
append 给场景中的字段追加验证规则
appendCheckField 添加一个需要验证的字段
removeCheckField 删除一个需要验证的字段

# only

指定场景需要验证的字段

public function only(array $fields): $this
  • $fields 为要验证的字段数组

# remove

移除场景中的字段的部分验证规则

public function remove(string $field, string $rule = null): $this
  • $field 为要移除规则的字段
  • $rule 为要移除的规则,多个规则用|分割,也可填入规则数组,$rule如为null,则清空该字段下的所有规则

# append

给场景中的字段需要追加验证规则

public function append(string $field, string|array|Closure $rule): $this
  • $field 为要追加规则的字段
  • $rule 为要追加的规则,多个规则用|分割,也可填入规则数组,或者闭包规则,闭包的格式和扩展方法一致

# sometimes

复杂条件验证

有时候你可能需要增加基于更复杂的条件逻辑的验证规则。例如,你可以希望某个指定字段在另一个字段的值超过 100 时才为必填。或者当某个指定字段存在时,另外两个字段才能具有给定的值

public function sometimes($attribute, $rules, callable $callback): $this
  • $attribute 要追加规则的字段,多个可传数组
  • $rules 要追加的规则,多个规则用|分割,也可填入规则数组
  • $callback 闭包方法,如果其返回true, 则额外的规则就会被加入

参数

传入 闭包 的 $data 参数是W7\Validate\Support\Storage\ValidateCollection的一个实例,可用来访问你的输入或文件对象。

我们可以根据一个参数或多个来处理其他参数的验证条件,更灵活的实现验证:

$scene->sometimes("name","required",function ($data) {
    return $data->type === 1;
});

# event

指定场景事件处理类,一个场景可以使用多个场景事件处理类

public function event(string $handler, ...$params): $this
  • $handler 处理器命名空间,可使用:class进行传入
  • $params 传递给中间件构建方法的参数,不限数量

# getData

此方法用来获取当前验证的数据

public function getData(string $key = '', $default = null)

默认获取全部验证的值

# getValidateData

此方法用来获取当前验证的数据,作用同getData,区别在于,此方法返回一个验证器集合

public function getValidateData(): ValidateCollection

# before

添加一个验证前的需要执行的方法,方法仅限本类的方法,方法的命名规则为before加方法名,方法的定义查看简单使用

public function before(string $callbackName, ...$params): $this
  • $callbackName 本类的方法名,不带前缀
  • $params 要传递给方法的参数

# after

添加一个验证后需要执行的方法,方法仅限本类的方法,方法的命名规则为after加方法名,方法的定义查看简单使用

public function after(string $callbackName, ...$params): $this
  • $callbackName 本类的方法名,不带前缀
  • $params 要传递给方法的参数

# appendCheckField

添加一个需要验证的字段,当需要根据Sql或者其他各种条件来增加一个需要验证的字段时,你就需要用到appendCheckField这个方法

public function appendCheckField(string $field): $this
  • $field 需要添加的字段名称

# removeCheckField

删除一个需要验证的字段,当需要根据Sql或者其他各种条件来删除一个正在验证的字段时,你就需要用到removeCheckField这个方法

public function removeCheckField(string $field): $this
  • $field 需要删除的字段名称

# setEventPriority

设置事件简易事件的优先级

public function setEventPriority(bool $priority): Validate
  • 当值为True时,执行顺序为:事件类beforeValidate->简易事件before->开始数据验证->简易事件after->事件类afterValidate
  • 当值为False时,执行顺序为:简易事件before->事件类beforeValidate->开始数据验证->事件类afterValidate->简易事件after

# default

设置或取消一个字段的默认值

public function default(string $field, $callback, bool $any = false): $this
  • $field 字段名称
  • $callback 默认值或者匿名函数等,如果为null,则取消该字段的默认值
  • $any 是否处理任意值,默认只处理空值

# filter

设置或取消一个字段的过滤器

public function filter(string $field, $callback): $this
  • $field 字段名称
  • $callback 全局函数名,匿名函数,过滤器类或其他

# next

public function next(string $name): $this
  • $name 下一个场景名或者场景选择器

使用说明参考:场景复用以及关联