前置处理

使用自定义验证规则之前,必须先定义自定义验证规则的命名空间前缀

ValidateConfig::instance()->setRulesPath('Itwmw\\App\\Model\\Validate\\Rules\\');

建议在Provider中定义验证相关的设置

优先级

验证器的内置规则优先级大于扩展规则,所以不要重名。

扩展全局规则

全局规则指在所有验证器中可以使用的规则

使用规则对象

验证器内有很多有用的验证规则;同时也支持自定义规则。注册自定义验证规则的方法之一,就是新建一个规则并继承Itwmw\Validate\Support\Rule\BaseRule。新的规则存放在你设置好的目录

一旦创建了规则,我们就可以定义它的行为。 passes方法接收属性值和名称,并根据属性值是否符合规则而返回truefalsemessage属性为验证失败时使用的验证错误消息,此错误消息可被验证器中定义的message覆盖:

隐式扩展

如果你想要在属性为空时执行规则对象,你应该实现 Itwmw\Validation\Support\Interfaces\ImplicitRule 接口。这个接口将充当验证器的「标记接口」;因此,它不包含你要实现的任何方法。

namespace Itwmw\App\Model\Validate\Rules;

class Chs extends BaseRule
{
    /**
     * 默认错误消息
     * @var string
     */
    protected $message = ':attribute的值只能具有中文';
    
    /**
     * 确定验证规则是否通过。
     *
     * @param mixed $attribute
     * @param mixed $value
     * @return bool
     */
    public function passes($attribute, $value): bool
    {
        return is_scalar($value) && 1 === preg_match('/^[\x{4e00}-\x{9fa5}]+$/u', (string)$value);
    }
}

一旦规则对象被定义好后,你可以通过将规则对象的实例和其他验证规则一起来传递给验证器:

protected $rule = [
    'title' => 'required|chs',
];

自定义扩展规则首字母可小写,也建议使用小写

规则对象错误消息格式化支持:规则类中格式化错误消息

规则也支持独立调用使用

Chs::make()->check("名字");

验证通过返回true,失败返回false

extend 扩展方法

在验证器中,可以使用 extend 方法注册一个规则,如:

class UserValidator extends Validate
{
}

$v = UserValidator::make();

$v->extend("chs",function ($attribute, $value, $parameters, $validator) {
    return is_scalar($value) && 1 === preg_match('/^[\x{4e00}-\x{9fa5}]+$/u', (string)$value);
}, ':attribute的值只能具有中文');

自定义的验证闭包接收四个参数:要被验证的属性名称 $attribute、属性的值 $value、传入验证规则的参数数组 $parameters 、以及 Validator 实例。 除了使用闭包,你也可以传入类和方法到extend方法中:

class Rules
{
    public function chs($attribute, $value, $parameters, $validator) {
        return is_scalar($value) && 1 === preg_match('/^[\x{4e00}-\x{9fa5}]+$/u', (string)$value);
    }
}

$v->extend("chs","Rules@chs", ':attribute的值只能具有中文');

如果你的方法为静态方法,还可以通过数组形式进行传入[完整类名,方法名]:

class Rules
{
    public static function chs($attribute, $value, $parameters, $validator)
    {
        return is_scalar($value) && 1 === preg_match('/^[\x{4e00}-\x{9fa5}]+$/u', (string)$value);
    }
}

$v->extend('chs', [Rules::class, 'chs'], ':attribute的值只能具有中文');

请注意

传入类和方法需要指定方法为public类型,类要传入完整的命名空间,如方法名没有传,则默认方法名为validate

replacer 错误信息替换器

如果需要定义错误消息,可以在extend的第三个参数中填入,或通过验证器的extendReplacer方法进行定义 extendReplacer方法接受两个参数ruleName和一个闭包参数,闭包接受四个参数:错误消息$message, 被验证的属性名称$attribute, 当前的规则名称$rule,传入验证规则的参数数组$parameters

$v->extendReplacer('chs', function ($message, $attribute, $rule, $parameters) {
    return '自定义错误消息';
});

除了使用闭包以外,也支持传入类和方法到extendReplacer方法中

$v->extendReplacer('chs', "Rules@chsMessage");
// 如果为静态方法
$v->extendReplacer('chs', [Rules::class, 'chsMessage']);

请注意

传入类和方法需要指定方法为public类型,类要传入完整的命名空间,如方法名没有传,则默认方法名为replace,可以覆盖默认规则的自定义消息

使用方式同使用规则对象

protected $rule = [
    'title' => 'required|chs',
];

extendImplicit 隐式扩展

默认情况下,当所要验证的属性不存在或包含一个空字符串时,使用包含自定义扩展的正常的验证规则是不会执行的。例如,unique 规则将不会检验空字符串:

$rules = ['name' => 'unique:users,name'];

$input = ['name' => ''];

// 验证通过

如果即使属性为空也要验证规则,则一定要暗示属性是必须的。要创建这样一个「隐式」扩展,可以使用 Validate中的extendImplicit() 方法:

$v->extendImplicit('foo', function ($attribute, $value, $parameters, $validator) {
    return $value == 'foo';
});

注意:「隐式」扩展只暗示该属性是必需的。至于它到底是缺失还是空值这取决于你。

extendDependent 依赖性验证器

如果想定义一个自定义扩展对数组进行验证时,我们会发现extendextendImplicit均不会解析*,这个时候就需要用到Validate中的extendDependent方法:

$v = new Validate();

$v->extendDependent('contains', function ($attribute, $value, $parameters, $validator) {
    // 下面验证器传来的$parameters是['*.provider'],当我们暗示这个自定义规则是依赖性的时候
    // 验证器往往会按照我们要验证的原始属性,用当前的指数替换星号,所以*.provider会被替换成0.provider
    // 现在我们可以使用Arr:get()来获取其他字段的值。
    // 所以这个自定义规则验证了属性值包含了其他给定属性的值。
    return str_contains($value,Arr::get($validator->getData(),$parameters[0]));
});

$v->setRules([
    '*.email' => 'contains:*.provider'
])->check([
    [
        'email' => '995645888@qq.com', 'provider' => 'qq.com'
    ]
]);

验证器内自定义规则

使用类方法

自定义规则也支持直接使用当前验证器类下的方法,规则为rule + 规则名,如ruleCheckLogin

请注意

这里的checkLogin和当前验证器下的其他方法注册的规则名不能重复,否则会覆盖

自定义规则方法接收四个参数:要被验证的属性名称 $attribute、属性的值 $value、传入验证规则的参数数组 $parameters 、以及 Validator 实例。

class Test extends Validate
{
    protected $rule = [
        'user' => 'required|alphaNum|checkLogin'
    ];

    protected $message = [
        'user.checkLogin' => '登录失败'
    ];

    public function ruleCheckLogin($attribute, $value, $parameters, $validator): bool
    {
        return 'admin' === $value;
    }
}

也可以通过$ruleMessage参数为类方法规则设定错误消息

class Test extends Validate
{
    protected $ruleMessage = [
        'chs' => ':attribute的值只能具有中文'
    ];

    protected function ruleChs($attribute, $value, $parameters, $validator): bool
    {
        return is_scalar($value) && 1 === preg_match('/^[\x{4e00}-\x{9fa5}]+$/u', (string)$value);
    }
}

正则表达式规则

支持直接使用正则验证,例如:

'id' => 'regex:/^\d+$/',

如果你的正则表达式中包含有|符号的话,必须使用数组方式定义。

'id' => ['regex:/^\d+$/']

也可以实现预定义正则表达式后直接调用,例如在验证器类中定义regex属性,然后在规则中使用regex: + 正则名称

class Test extends \Itwmw\Validate\Validate
{
    protected $regex = [
        'number' => '/^\d+$/'
    ];

    protected $rule = [
        'id' => 'regex:number'
    ];
}



 



 


自定义规则传入参数

自定义规则,和其他规则一样,也支持传入参数,类似于max:100,in:0,1,2此类,参数将按顺序传入自定义规则类中的构造函数中,如下:

class Length extends BaseRule
{
    protected $message = ':attribute的长度不符合要求';

    protected $size;

    public function __construct(int $size)
    {
        $this->size = $size;
    }

    public function passes($attribute, $value): bool
    {
        return strlen($value) === $this->size;
    }
}







 










Or规则

当你需要多个规则中只要有一个通过即可时,可以使用 or 规则,例如:

class User extends Validate {
    protected $rule = [
        'username' => 'required|or:email,mobile'
    ];
}


 


当你的 username 满足 emailmobile 即可通过验证:

User::make()->check([
    'username' => '995645888@qq.com'
]);

User::make()->check([
    'username' => '18899996666'
]);

 



 

995645888@qq.com18899996666 均满足要求

使用规则组

or 规则也支持使用规则组,例如:

class User extends Validate {
    protected $group = [
        'username' => 'email|mobile'
    ];

    protected $rule = [
        'username' => 'required|or:username'
    ];
}

也可以使用多个规则组,例如:

class User extends Validate
{
    protected $group = [
        'username'    => 'email|mobile',
        'username_nl' => 'alpha|chs'
    ];

    protected $rule = [
        'username' => 'required|or:username,username_nl'
    ];
}

此定义下,只要username满足usernameusername_nl两个规则组中任意一个规则均可通过验证

也支持规则组和规则一起使用,例如:

class User extends Validate
{
    protected $group = [
        'username_nl'       => 'alpha|chs',
        'username_specific' => 'in:admin123,root520'
    ];

    protected $rule = [
        'username' => 'required|or:username_specific,username_nl,email,mobile'
    ];
}

在这个例子中,username满足username_specificusername_nl两个规则组中任意一个规则,或者满足emailmobile中任意一个规则即可通过验证

User::make()->check([
    'username' => '995645888@qq.com'
]);

User::make()->check([
    'username' => '18899996666'
]);

User::make()->check([
    'username' => '虞灪'
]);

User::make()->check([
    'username' => 'yapyuyu'
]);

User::make()->check([
    'username' => 'admin123'
]);

User::make()->check([
    'username' => 'root520'
]);

以上均可通过验证