Validate
Testing Is Documentation
构造器函数原型
public function __construct(array $data = [], array $rules = [], array $names = [], array $messages = []);
- $data 验证的数据
- $rules 验证规则
- $names 校验名字隐射
- $messages 校验失败消息
可以通过构造器传递参数,也可以通过 name
,message
等方法传入。
Uses
<?php
use Leevel\Di\Container;
use Leevel\Kernel\Utils\Api;
use Leevel\Validate\IValidator;
use Leevel\Validate\Validate;
use Leevel\Validate\Validator;
use Leevel\Validate\ValidatorException;
use PHPUnit\Framework\Attributes\DataProvider;
验证器基本使用方法
可以通过 success
判断是否通过验证,error
返回错误消息。
public function testBaseUse(): void
{
$validate = new Validator(
[
'name' => '小牛哥',
],
[
'name' => 'required|max_length:10',
],
[
'name' => '用户名',
]
);
$this->assertInstanceof(IValidator::class, $validate);
$rule = <<<'eot'
{
"name": [
[
"required",
[]
],
[
"max_length",
[
"10"
]
]
]
}
eot;
self::assertTrue($validate->success());
self::assertFalse($validate->fail());
self::assertSame([], $validate->error());
self::assertSame([], $validate->getMessage());
self::assertSame(['name' => '小牛哥'], $validate->getData());
self::assertSame(
$rule,
$this->varJson(
$validate->getRule()
)
);
}
验证器规则支持数组写法
可以通过 success
判断是否通过验证,error
返回错误消息。
public function testRuleIsArray(): void
{
$validate = new Validator(
[
'name' => '小牛哥',
],
[
'name' => ['required', 'max_length:10'],
],
[
'name' => '用户名',
]
);
$this->assertInstanceof(IValidator::class, $validate);
$rule = <<<'eot'
{
"name": [
[
"required",
[]
],
[
"max_length",
[
"10"
]
]
]
}
eot;
self::assertTrue($validate->success());
self::assertFalse($validate->fail());
self::assertSame([], $validate->error());
self::assertSame([], $validate->getMessage());
self::assertSame(['name' => '小牛哥'], $validate->getData());
self::assertSame(
$rule,
$this->varJson(
$validate->getRule()
)
);
}
验证器规则支持数组写法:每一项都是一个数组(第一个是规则,第一个是参数非数组兼容为数组)
可以通过 success
判断是否通过验证,error
返回错误消息。
public function testRuleIsArray2(): void
{
$validate = new Validator(
[
'name' => '小牛哥',
],
[
'name' => ['required', ['max_length', 10]],
],
[
'name' => '用户名',
]
);
$this->assertInstanceof(IValidator::class, $validate);
$rule = <<<'eot'
{
"name": [
[
"required",
[]
],
[
"max_length",
[
10
]
]
]
}
eot;
self::assertTrue($validate->success());
self::assertFalse($validate->fail());
self::assertSame([], $validate->error());
self::assertSame([], $validate->getMessage());
self::assertSame(['name' => '小牛哥'], $validate->getData());
self::assertSame(
$rule,
$this->varJson(
$validate->getRule()
)
);
}
验证器规则支持数组写法:每一项都是一个数组(第一个是规则,第一个是参数数组用法)
可以通过 success
判断是否通过验证,error
返回错误消息。
public function testRuleIsArray3(): void
{
$validate = new Validator(
[
'name' => '小牛哥',
],
[
'name' => ['required', ['max_length', [10]]],
],
[
'name' => '用户名',
]
);
$this->assertInstanceof(IValidator::class, $validate);
$rule = <<<'eot'
{
"name": [
[
"required",
[]
],
[
"max_length",
[
10
]
]
]
}
eot;
self::assertTrue($validate->success());
self::assertFalse($validate->fail());
self::assertSame([], $validate->error());
self::assertSame([], $validate->getMessage());
self::assertSame(['name' => '小牛哥'], $validate->getData());
self::assertSame(
$rule,
$this->varJson(
$validate->getRule()
)
);
}
验证器规则支持数组每一项字符串支持分隔:可以用于实际业务中合并验证规则的需求
可以通过 success
判断是否通过验证,error
返回错误消息。
public function testRuleIsArrayStringMixed(): void
{
$validate = new Validator(
[
'name' => '小牛哥',
],
[
'name' => ['required|chinese|min_length:1', ['max_length', [10]]],
],
[
'name' => '用户名',
]
);
$this->assertInstanceof(IValidator::class, $validate);
$rule = <<<'eot'
{
"name": [
[
"required",
[]
],
[
"chinese",
[]
],
[
"min_length",
[
"1"
]
],
[
"max_length",
[
10
]
]
]
}
eot;
self::assertTrue($validate->success());
self::assertFalse($validate->fail());
self::assertSame([], $validate->error());
self::assertSame([], $validate->getMessage());
self::assertSame(['name' => '小牛哥'], $validate->getData());
self::assertSame(
$rule,
$this->varJson(
$validate->getRule()
)
);
}
make 创建验证器
public function testMake(): void
{
$validate = Validator::make(
[
'name' => '小牛哥',
],
[
'name' => 'required|max_length:10',
],
[
'name' => '用户名',
]
);
$rule = <<<'eot'
{
"name": [
[
"required",
[]
],
[
"max_length",
[
"10"
]
]
]
}
eot;
self::assertTrue($validate->success());
self::assertFalse($validate->fail());
self::assertSame([], $validate->error());
self::assertSame([], $validate->getMessage());
self::assertSame(['name' => '小牛哥'], $validate->getData());
self::assertSame(
$rule,
$this->varJson(
$validate->getRule()
)
);
}
验证器校验错误
public function testError(): void
{
$validate = new Validator(
[
'name' => '小牛哥',
],
[
'name' => 'required|min_length:20',
],
[
'name' => '用户名',
]
);
$error = <<<'eot'
{
"name": [
"用户名 不满足最小长度 20"
]
}
eot;
self::assertFalse($validate->success());
self::assertTrue($validate->fail());
self::assertSame(
$error,
$this->varJson(
$validate->error()
)
);
}
设置校验数据
public function testData(): void
{
$validate = new Validator(
[
'name' => '中国',
],
[
'name' => 'required|min_length:20',
],
[
'name' => '用户名',
]
);
$error = <<<'eot'
{
"name": [
"用户名 不满足最小长度 20"
]
}
eot;
self::assertFalse($validate->success());
self::assertTrue($validate->fail());
self::assertSame(
$error,
$this->varJson(
$validate->error()
)
);
$validate->data(['name' => '12345678901234567890']);
self::assertTrue($validate->success());
self::assertFalse($validate->fail());
}
添加校验数据
public function testAddData(): void
{
$validate = new Validator(
[
],
[
'name' => 'required|min_length:20|'.IValidator::OPTIONAL,
],
[
'name' => '用户名',
]
);
$error = <<<'eot'
{
"name": [
"用户名 不满足最小长度 20"
]
}
eot;
self::assertTrue($validate->success());
self::assertFalse($validate->fail());
$validate->addData(['name' => '中国']);
self::assertFalse($validate->success());
self::assertTrue($validate->fail());
self::assertSame(
$error,
$this->varJson(
$validate->error()
)
);
}
设置校验规则
public function testRule(): void
{
$validate = new Validator(
[
'name' => '中国',
],
[
],
[
'name' => '用户名',
]
);
$error = <<<'eot'
{
"name": [
"用户名 不满足最小长度 20"
]
}
eot;
self::assertTrue($validate->success());
self::assertFalse($validate->fail());
$validate->rule(['name' => 'required|min_length:20']);
self::assertFalse($validate->success());
self::assertTrue($validate->fail());
self::assertSame(
$error,
$this->varJson(
$validate->error()
)
);
$validate->rule(['name' => 'required|max_length:20']);
self::assertTrue($validate->success());
self::assertFalse($validate->fail());
}
设置校验规则支持条件
第一个闭包条件参数不为空,如果闭包返回 true
则添加改验证规则,否则忽略。
public function testRuleIf(): void
{
$validate = new Validator(
[
'name' => '中国',
],
[
],
[
'name' => '用户名',
]
);
self::assertTrue($validate->success());
self::assertFalse($validate->fail());
$validate->rule(['name' => 'required|min_length:20'], function (array $data) {
$this->assertSame(['name' => '中国'], $data);
return false;
});
$rule = <<<'eot'
[]
eot;
self::assertSame(
$rule,
$this->varJson(
$validate->getRule()
)
);
self::assertTrue($validate->success());
self::assertFalse($validate->fail());
}
添加校验规则
public function testAddRule(): void
{
$validate = new Validator(
[
'name' => '中国',
],
[
],
[
'name' => '用户名',
]
);
self::assertTrue($validate->success());
self::assertFalse($validate->fail());
$validate->addRule(['name' => 'required|min_length:20']);
$rule = <<<'eot'
{
"name": [
[
"required",
[]
],
[
"min_length",
[
"20"
]
]
]
}
eot;
self::assertSame(
$rule,
$this->varJson(
$validate->getRule()
)
);
self::assertFalse($validate->success());
self::assertTrue($validate->fail());
$error = <<<'eot'
{
"name": [
"用户名 不满足最小长度 20"
]
}
eot;
self::assertSame(
$error,
$this->varJson(
$validate->error()
)
);
}
添加校验规则支持条件
第一个闭包条件参数不为空,如果闭包返回 true
则添加改验证规则,否则忽略。
public function testAddRuleIf(): void
{
$validate = new Validator(
[
'name' => '中国',
],
[
],
[
'name' => '用户名',
]
);
self::assertTrue($validate->success());
self::assertFalse($validate->fail());
$validate->addRule(['name' => 'required|min_length:20'], function (array $data) {
$this->assertSame(['name' => '中国'], $data);
return false;
});
$rule = <<<'eot'
[]
eot;
self::assertSame(
$rule,
$this->varJson(
$validate->getRule()
)
);
self::assertTrue($validate->success());
self::assertFalse($validate->fail());
}
设置验证消息
public function testMessage(): void
{
$validate = new Validator(
[
'name' => '中国',
],
[
'name' => 'required|min_length:20',
],
[
'name' => '用户名',
]
);
$error = <<<'eot'
{
"name": [
"用户名 不满足最小长度 20"
]
}
eot;
self::assertFalse($validate->success());
self::assertTrue($validate->fail());
self::assertSame(
$error,
$this->varJson(
$validate->error()
)
);
$validate->message(['min_length' => '{field} not min {rule}']);
$error = <<<'eot'
{
"name": [
"用户名 not min 20"
]
}
eot;
self::assertFalse($validate->success());
self::assertTrue($validate->fail());
self::assertSame(
$error,
$this->varJson(
$validate->error()
)
);
}
添加验证消息
设置规则所有字段的验证消息。
public function testAddMessage(): void
{
$validate = new Validator(
[
'name' => '中国',
],
[
'name' => 'required|min_length:20',
],
[
'name' => '用户名',
]
);
$error = <<<'eot'
{
"name": [
"用户名 不满足最小长度 20"
]
}
eot;
self::assertFalse($validate->success());
self::assertTrue($validate->fail());
self::assertSame(
$error,
$this->varJson(
$validate->error()
)
);
$validate->addMessage(['min_length' => '{field} foo bar {rule}']);
$error = <<<'eot'
{
"name": [
"用户名 foo bar 20"
]
}
eot;
self::assertFalse($validate->success());
self::assertTrue($validate->fail());
self::assertSame(
$error,
$this->varJson(
$validate->error()
)
);
}
添加指定字段验证规则消息
可以单独为某个字段指定验证消息规则,其它字段验证消息保持不变。
public function testAddMessageForOneField(): void
{
$validate = new Validator(
[
'name' => '中国',
],
[
'name' => 'required|min_length:20',
],
[
'name' => '用户名',
]
);
$error = <<<'eot'
{
"name": [
"用户名 不满足最小长度 20"
]
}
eot;
self::assertFalse($validate->success());
self::assertTrue($validate->fail());
self::assertSame(
$error,
$this->varJson(
$validate->error()
)
);
$validate->addMessage(['name' => ['min_length' => '{field} hello world {rule}']]);
$error = <<<'eot'
{
"name": [
"用户名 hello world 20"
]
}
eot;
self::assertFalse($validate->success());
self::assertTrue($validate->fail());
self::assertSame(
$error,
$this->varJson(
$validate->error()
)
);
}
添加指定字段验证规则消息(圆点分隔)
通过圆点 .
分隔开来。
public function testAddMessageForOneFieldSeparateByDot(): void
{
$validate = new Validator(
[
'name' => '中国',
],
[
'name' => 'required|min_length:20',
],
[
'name' => '用户名',
]
);
$error = <<<'eot'
{
"name": [
"用户名 不满足最小长度 20"
]
}
eot;
self::assertFalse($validate->success());
self::assertTrue($validate->fail());
self::assertSame(
$error,
$this->varJson(
$validate->error()
)
);
$validate->addMessage(['name.min_length' => '{field} hehe {rule}']);
$error = <<<'eot'
{
"name": [
"用户名 hehe 20"
]
}
eot;
self::assertFalse($validate->success());
self::assertTrue($validate->fail());
self::assertSame(
$error,
$this->varJson(
$validate->error()
)
);
}
添加指定多层子字段验证规则消息(圆点分隔)
通过圆点 .
分隔开来。
public function testSubDataWithSubMessage(): void
{
$validate = new Validator(
[
'name' => ['sub' => ['sub' => '']],
],
[
'name.sub.sub' => 'required|'.IValidator::MUST,
],
[
'name' => '歌曲',
]
);
self::assertFalse($validate->success());
self::assertTrue($validate->fail());
$error = <<<'eot'
{
"name.sub.sub": [
"name.sub.sub 不能为空"
]
}
eot;
self::assertSame(
$error,
$this->varJson(
$validate->error()
)
);
$validate->addMessage(['name.sub.sub' => ['required' => '字段 {field} 不能为空']]);
self::assertFalse($validate->success());
self::assertTrue($validate->fail());
$error = <<<'eot'
{
"name.sub.sub": [
"字段 name.sub.sub 不能为空"
]
}
eot;
self::assertSame(
$error,
$this->varJson(
$validate->error()
)
);
}
添加通配符字段验证规则消息
通过 *
来代表通配符。
public function testWildcardSubDataWithSubMessage(): void
{
$validate = new Validator(
[
'name' => ['sub' => ['sub' => '']],
],
[
'name.sub.sub' => 'required|'.IValidator::MUST,
],
[
'name' => '歌曲',
]
);
self::assertFalse($validate->success());
self::assertTrue($validate->fail());
$error = <<<'eot'
{
"name.sub.sub": [
"name.sub.sub 不能为空"
]
}
eot;
self::assertSame(
$error,
$this->varJson(
$validate->error()
)
);
$validate->addMessage(['name*' => ['required' => 'sub {field} must have value']]);
self::assertFalse($validate->success());
self::assertTrue($validate->fail());
$error = <<<'eot'
{
"name.sub.sub": [
"sub name.sub.sub must have value"
]
}
eot;
self::assertSame(
$error,
$this->varJson(
$validate->error()
)
);
}
设置验证字段隐射
public function testName(): void
{
$validate = new Validator(
[
'name' => '中国',
],
[
'name' => 'required|min_length:20',
],
[
'name' => '用户名',
]
);
$error = <<<'eot'
{
"name": [
"用户名 不满足最小长度 20"
]
}
eot;
self::assertFalse($validate->success());
self::assertTrue($validate->fail());
self::assertSame(['name' => '用户名'], $validate->getName());
self::assertSame(
$error,
$this->varJson(
$validate->error()
)
);
$validate->name(['name' => 'username']);
$error = <<<'eot'
{
"name": [
"username 不满足最小长度 20"
]
}
eot;
self::assertFalse($validate->success());
self::assertTrue($validate->fail());
self::assertSame(
$error,
$this->varJson(
$validate->error()
)
);
}
添加验证字段隐射
public function testAddName(): void
{
$validate = new Validator(
[
'name' => '中国',
],
[
'name' => 'required|min_length:20',
],
[
'name' => '用户名',
]
);
$error = <<<'eot'
{
"name": [
"用户名 不满足最小长度 20"
]
}
eot;
self::assertFalse($validate->success());
self::assertTrue($validate->fail());
self::assertSame(['name' => '用户名'], $validate->getName());
self::assertSame(
$error,
$this->varJson(
$validate->error()
)
);
$validate->addName(['name' => 'hello world']);
$error = <<<'eot'
{
"name": [
"hello world 不满足最小长度 20"
]
}
eot;
self::assertFalse($validate->success());
self::assertTrue($validate->fail());
self::assertSame(
$error,
$this->varJson(
$validate->error()
)
);
}
验证后回调
无论成功或者失败都会执行回调。
public function testAfter(): void
{
$validate = new Validator(
[
'name' => '成都',
],
[
'name' => 'required|max_length:10',
],
[
'name' => '地名',
]
);
$validate->after(function ($v): void {
$this->assertSame(['name' => '地名'], $v->getName());
});
self::assertTrue($validate->success());
self::assertFalse($validate->fail());
}
自定义扩展验证规则
public function testExtend(): void
{
$validate = new Validator(
[
'name' => 1,
],
[
'name' => 'required|custom_rule:10',
],
[
'name' => '地名',
]
);
$validate->extend('custom_rule', static function ($value, array $param, IValidator $validator, string $field): bool {
if (1 === $value) {
return true;
}
return false;
});
self::assertTrue($validate->success());
self::assertFalse($validate->fail());
$validate->data(['name' => 0]);
self::assertFalse($validate->success());
self::assertTrue($validate->fail());
}
直接调用验证规则
public function testCall(): void
{
$validate = new Validator();
self::assertTrue($validate->minLength('成都', 1));
self::assertTrue($validate->minLength('成都', 2));
self::assertFalse($validate->minLength('成都', 3));
self::assertFalse($validate->alpha('成都'));
self::assertTrue($validate->alpha('cd'));
}
直接调用自定义验证规则
public function testCallCustom(): void
{
$validate = new Validator();
$validate->extend('custom_foo_bar', static function (string $field, $value, array $param): bool {
if ('成都' === $value) {
return true;
}
return false;
});
self::assertTrue($validate->customFooBar('成都'));
self::assertFalse($validate->customFooBar('魂之挽歌'));
}
自定义扩展验证规则(类)
自定义扩展规则可以为一个独立的类,例如下面的例子。
namespace Tests\Validate;
class ExtendClassTest1
{
public function handle($value, array $param, IValidator $validator, string $field): bool
{
if (1 === $value) {
return true;
}
return false;
}
public function handle2($value, array $param, IValidator $validator, string $field): bool
{
if (2 === $value) {
return true;
}
return false;
}
}
默认情况下,此时自定义类的 handle
方法将作为验证入口。
public function testCallExtendClass(): void
{
$validate = new Validator(
[
'name' => 1,
],
[
'name' => 'custom_foobar',
],
[
'name' => '地名',
]
);
$container = new Container();
$validate->setContainer($container);
$validate->extend('custom_foobar', ExtendClassTest1::class);
self::assertTrue($validate->success());
$validate->data(['name' => 'foo']);
self::assertFalse($validate->success());
}
自定义扩展验证规则(类),指定验证方法
自定义扩展规则可以为一个独立的类,例如下面的例子。
namespace Tests\Validate;
class ExtendClassTest1
{
public function handle($value, array $param, IValidator $validator, string $field): bool
{
if (1 === $value) {
return true;
}
return false;
}
public function handle2($value, array $param, IValidator $validator, string $field): bool
{
if (2 === $value) {
return true;
}
return false;
}
}
指定方法情况下,通过 @
分隔开来,此时自定义类的 handle2
方法将作为验证入口。
public function testCallExtendClassWithCustomMethod(): void
{
$validate = new Validator(
[
'name' => 2,
],
[
'name' => 'custom_foobar',
],
[
'name' => '地名',
]
);
$container = new Container();
$validate->setContainer($container);
$validate->extend('custom_foobar', ExtendClassTest1::class.'@handle2');
self::assertTrue($validate->success());
$validate->data(['name' => 'foo']);
self::assertFalse($validate->success());
}
验证失败则跳过其它验证规则
只需要在校验规则中加入 SKIP_OTHER
即可。
public function testShouldSkipOther(): void
{
$validate = new Validator(
[
'name' => '',
'value' => '',
],
[
'name' => 'required|alpha',
'value' => 'required',
],
[
'name' => '地名',
'value' => '值',
]
);
$error = <<<'eot'
{
"name": [
"地名 不能为空",
"地名 只能是字母"
],
"value": [
"值 不能为空"
]
}
eot;
self::assertFalse($validate->success());
self::assertTrue($validate->fail());
self::assertSame(['name' => '地名', 'value' => '值'], $validate->getName());
self::assertSame(
$error,
$this->varJson(
$validate->error()
)
);
$validate->addRule(['name' => 'required|alpha|'.IValidator::SKIP_OTHER]);
self::assertFalse($validate->success());
self::assertTrue($validate->fail());
$error = <<<'eot'
{
"name": [
"地名 不能为空"
]
}
eot;
self::assertSame(
$error,
$this->varJson(
$validate->error()
)
);
}
验证失败则跳过自身其它验证规则
只需要在校验规则中加入 SKIP_SELF
即可,只会跳过当前字段的其他验证规则,而其它字段的验证规则不受影响。
public function testShouldSkipSelf(): void
{
$validate = new Validator(
[
'name' => '',
'value' => '',
],
[
'name' => 'required|alpha',
'value' => 'required',
],
[
'name' => '地名',
'value' => '值',
]
);
$error = <<<'eot'
{
"name": [
"地名 不能为空",
"地名 只能是字母"
],
"value": [
"值 不能为空"
]
}
eot;
self::assertFalse($validate->success());
self::assertTrue($validate->fail());
self::assertSame(['name' => '地名', 'value' => '值'], $validate->getName());
self::assertSame(
$error,
$this->varJson(
$validate->error()
)
);
$validate->addRule(['name' => 'required|alpha|'.IValidator::SKIP_SELF]);
self::assertFalse($validate->success());
self::assertTrue($validate->fail());
$error = <<<'eot'
{
"name": [
"地名 不能为空"
],
"value": [
"值 不能为空"
]
}
eot;
self::assertSame(
$error,
$this->varJson(
$validate->error()
)
);
}
值为 null 会跳过可选验证规则
如果校验规则中有 OPTIONAL
,那么字段值为 null
则不会执行验证规则。
public function testOptional(): void
{
$validate = new Validator(
[
'name' => null,
],
[
'name' => 'required|'.IValidator::OPTIONAL,
],
[
'name' => '地名',
]
);
self::assertTrue($validate->success());
self::assertFalse($validate->fail());
self::assertSame(['name' => '地名'], $validate->getName());
}
值为 null或者空字符串 会跳过可选字符串验证规则
如果校验规则中有 OPTIONAL_STRING
,那么字段值为 null
或者空字符串则不会执行验证规则。
public function testOptionalString(): void
{
$validate = new Validator(
[
'name' => null,
],
[
'name' => 'required|'.IValidator::OPTIONAL_STRING,
],
[
'name' => '地名',
]
);
self::assertTrue($validate->success());
self::assertFalse($validate->fail());
self::assertSame(['name' => '地名'], $validate->getName());
$validate = new Validator(
[
'name' => '',
],
[
'name' => 'required|'.IValidator::OPTIONAL_STRING,
],
[
'name' => '地名',
]
);
self::assertTrue($validate->success());
self::assertFalse($validate->fail());
self::assertSame(['name' => '地名'], $validate->getName());
}
值为 null 默认必须验证
我们加入 MUST
或者默认不指定,那么 null
也会执行验证。
public function testMustRequired(): void
{
$validate = new Validator(
[
'name' => null,
],
[
'name' => 'required|'.IValidator::OPTIONAL,
],
[
'name' => '地名',
]
);
self::assertTrue($validate->success());
self::assertFalse($validate->fail());
self::assertSame(['name' => '地名'], $validate->getName());
$validate->rule(['name' => 'required']);
self::assertFalse($validate->success());
self::assertTrue($validate->fail());
$error = <<<'eot'
{
"name": [
"地名 不能为空"
]
}
eot;
self::assertSame(
$error,
$this->varJson(
$validate->error()
)
);
$validate->data(['name' => null]);
self::assertFalse($validate->success());
self::assertTrue($validate->fail());
$error = <<<'eot'
{
"name": [
"地名 不能为空"
]
}
eot;
self::assertSame(
$error,
$this->varJson(
$validate->error()
)
);
}
通配符验证规则支持
可以通过 *
来表示通配符验证规则。
public function testWildcardRule(): void
{
$validate = new Validator(
[
'name' => '',
'nafoo' => '',
'nabar' => '',
],
[
],
[
'name' => '地名',
'nafoo' => 'foo',
'nabar' => 'bar',
]
);
self::assertTrue($validate->success());
self::assertFalse($validate->fail());
$validate->rule(['na*' => 'required']);
self::assertFalse($validate->success());
self::assertTrue($validate->fail());
self::assertSame(['name' => '地名', 'nafoo' => 'foo', 'nabar' => 'bar'], $validate->getName());
$data = <<<'eot'
{
"name": "",
"nafoo": "",
"nabar": ""
}
eot;
self::assertSame(
$data,
$this->varJson(
$validate->getData()
)
);
$rule = <<<'eot'
{
"name": [
[
"required",
[]
]
],
"nafoo": [
[
"required",
[]
]
],
"nabar": [
[
"required",
[]
]
]
}
eot;
self::assertSame(
$rule,
$this->varJson(
$validate->getRule(),
1
)
);
$error = <<<'eot'
{
"name": [
"地名 不能为空"
],
"nafoo": [
"foo 不能为空"
],
"nabar": [
"bar 不能为空"
]
}
eot;
self::assertSame(
$error,
$this->varJson(
$validate->error(),
2
)
);
}
类的静态方法验证规则支持
可以直接指定类的静态方法为验证规则,例如下面的例子。
namespace Tests\Validate;
class ClassStaticDemo1
{
public static function handle(mixed $value, array $param, Validator $validator): bool
{
return false;
}
public static function demoValidator1(mixed $value, array $param, Validator $validator): bool
{
return true;
}
public static function demoValidator2(mixed $value, array $param, Validator $validator): bool
{
return false;
}
public static function demoValidator3(mixed $value, array $param, Validator $validator): bool
{
return 'foo' === $value;
}
public static function demoValidator4(mixed $value, array $param, Validator $validator): bool
{
throw new ValidatorException('我的名字验证失败');
}
}
指定方法情况下,通过 @
分隔开来,此时自定义类的 demoValidator1
方法将作为验证入口。
public function test2(): void
{
$validate = new Validator(
[
'name' => 2,
],
[
'name' => [
ClassStaticDemo1::class.'@demoValidator1',
],
],
[
'name' => '地名',
]
);
$container = new Container();
$validate->setContainer($container);
self::assertTrue($validate->success());
$validate->data(['name' => 'foo']);
self::assertTrue($validate->success());
}
类的静态方法验证规则支持通过异常抛出错误
可以在类的静态方法中抛出异常消息,异常必须为\Leevel\Validate\ValidatorException,例如下面的例子。
namespace Tests\Validate;
class ClassStaticDemo1
{
public static function handle(mixed $value, array $param, Validator $validator): bool
{
return false;
}
public static function demoValidator1(mixed $value, array $param, Validator $validator): bool
{
return true;
}
public static function demoValidator2(mixed $value, array $param, Validator $validator): bool
{
return false;
}
public static function demoValidator3(mixed $value, array $param, Validator $validator): bool
{
return 'foo' === $value;
}
public static function demoValidator4(mixed $value, array $param, Validator $validator): bool
{
throw new ValidatorException('我的名字验证失败');
}
}
指定方法情况下,通过 @
分隔开来,此时自定义类的 demoValidator4
方法将作为验证入口。
public function test6(): void
{
$validate = new Validator(
[
'name' => 2,
],
[
'name' => [
ClassStaticDemo1::class.'@demoValidator4',
],
],
[
'name' => '地名',
]
);
$container = new Container();
$validate->setContainer($container);
self::assertFalse($validate->success());
$error = <<<'eot'
"name": [
"我的名字验证失败"
]
self::assertSame(
$error,
$this->varJson(
$validate->error()
)
);
$validate->data(['name' => 'foo']);
self::assertFalse($validate->success());
}
验证器支持反义规则
定义反义规则,只需要在规则前面加上英文感叹号即可。
public function test7(): void
{
$validate = new Validator(
[
'name' => 8,
],
[
'name' => '!min:5',
],
[
'name' => '地名',
]
);
self::assertFalse($validate->success());
self::assertTrue($validate->fail());
self::assertSame(['name' => '地名'], $validate->getName());
$error = <<<'eot'
"name": [
"不满足【地名 值不能小于 5】"
]
self::assertSame(
$error,
$this->varJson(
$validate->error()
)
);
}