fi1a / validation
PHP 表单值和数据的验证(检查)
Requires
- php: ^7.3 || ^8
- ext-json: *
- fi1a/collection: ^2.0
- fi1a/format: ^2.0
- fi1a/hydrator: ^1.1
- fi1a/tokenizer: ^1.1
Requires (Dev)
- captainhook/captainhook: ^5.4
- phpunit/phpunit: ^9.3
- slevomat/coding-standard: ^6.3
- squizlabs/php_codesniffer: ^3.5
- vimeo/psalm: ^4.3
README
验证意味着检查用户填写的数据。此包提供了在表单数据提交后对服务器端进行检查的机会。
功能
- 检查(验证)数组和单独值的验证;
- 检查(验证)表单值和上传文件的验证;
- 支持带有脚本的规则集;
- 可以更改字段名称;
- 可以更改错误文本;
- 可以扩展自定义验证规则;
- 脚本和规则集;
- 检查公共字段的对象。
安装
可以使用 Composer 将此包作为依赖项安装。
composer require fi1a/validation
检查表单字段数据
要检查表单字段数据,需要使用类 \Fi1a\Validation\Validator
中的 make
方法。创建验证对象后,需要调用 validate
方法来检查传入的值。调用 validate
方法时,返回一个检查结果对象 \Fi1a\Validation\Result
。
示例
use Fi1a\Validation\Validator; $validator = new Validator(); $validation = $validator->make($_POST + $_FILES, [ 'id' => 'required|integer', 'email' => 'required|email', 'password' => 'required|minLength(8)', 'confirm_password' => 'required|same("password")', 'tags' => 'array|required', 'tags:*:id' => 'required|numeric', ]); $result = $validation->validate(); if (!$result->isSuccess()) { echo $result->getErrors()->join("\n"); }
检查单个字段
要检查单个字段,需要使用规则链中的一个类。规则链使用 "Fluent interface" 实现用于声明使用的规则。
规则链 "值必须满足所有规则"(Fi1a\Validation\AllOf
)
use Fi1a\Validation\AllOf; $result = AllOf::create()->required()->integer()->validate('abc'); if (!$result->isSuccess()) { echo $result->getErrors()->join("; "); // "Значение не является целым числом" }
规则链 "值必须满足其中一个规则"(Fi1a\Validation\OneOf
)
use Fi1a\Validation\OneOf; $chain = OneOf::create()->integer()->boolean(); $result = $chain->validate(true); echo $result->isSuccess(); // true $result = $chain->validate(10); echo $result->isSuccess(); // true $result = $chain->validate(null); echo $result->isSuccess(); // false echo $result->getErrors()->join("; "); // Значение не является целым числом; Значение должно быть логическим
规则链示例。值可以是大于10的数字或最小长度为2的字符串
use Fi1a\Validation\AllOf; use Fi1a\Validation\OneOf; $chain = OneOf::create( AllOf::create()->numeric()->min(10), AllOf::create()->alpha()->minLength(2) ); $result = $chain->validate(20); echo $result->isSuccess(); // true $result = $chain->validate('abc'); echo $result->isSuccess(); // true $result = $chain->validate('a'); echo $result->isSuccess(); // false echo $result->getErrors()->join("; "); // Значение не является числом; Значение должно быть минимум 10; Длина значения должна быть больше 2
检查对象
可以通过传递对象而不是值数组来检查对象属性值(只检查对象的公共属性)
class DTO { public $propertyA = 100; public $propertyB = 'string'; public $propertyC; public $propertyD = true; public function getPropertyD(): bool { return $this->propertyD; } } use Fi1a\Validation\Validator; $validator = new Validator(); $validation = $validator->make( new DTO(), [ 'propertyA' => 'required|integer', 'propertyB' => 'required', 'propertyC' => 'null', 'propertyD' => 'required|boolean', ] ); $result = $validation->validate(); $result->isSuccess(); // true
错误消息
可以在创建验证对象时通过 make
方法传递包含错误消息的数组,或者稍后通过 setMessage
或 setMessages
方法对象来设置错误消息。也可以在规则集中定义错误消息 Fi1a\Validation\RuleSetInterface
(通过方法 getMessages
返回的数组)。
use Fi1a\Validation\Validator; $validator = new Validator(); $validation = $validator->make($_POST + $_FILES, [ 'firstName' => 'required|betweenLength(2, 40)', 'lastName' => 'required|betweenLength(2, 40)', ], [ 'required' => 'Очень обязательное поле', 'lastName|required' => '"Фамилия" обязательное поле', ]); $result = $validation->validate(); if (!$result->isSuccess()) { echo $result->getErrors()->join("; "); // Очень обязательное поле; "Фамилия" обязательное поле } $validation->setMessage('firstName|required', 'Очень обязательное поле 2'); $validation->setMessage('required', '"Фамилия" обязательное поле 2'); $validation->setMessage('lastName|required', null); $result = $validation->validate(); if (!$result->isSuccess()) { echo $result->getErrors()->join("; "); // Очень обязательное поле 2; "Фамилия" обязательное поле 2 }
字段标题
可以在创建验证对象时通过 make
方法传递标题,或者稍后通过 setTitle
或 setTitles
方法对象来设置标题。也可以在规则集中定义标题 Fi1a.Validation\RuleSetInterface
(通过方法 getTitles
返回的数组)。
use Fi1a\Validation\Validator; $validator = new Validator(); $validation = $validator->make($_POST + $_FILES, [ 'firstName' => 'required|betweenLength(2, 40)', 'lastName' => 'required|betweenLength(2, 40)', ], [], [ 'firstName' => 'Имя', 'lastName' => 'Фамилия', ]); $result = $validation->validate(); if (!$result->isSuccess()) { echo $result->getErrors()->join("; "); // Значение "Имя" является обязательным; Значение "Фамилия" является обязательным } $validation->setTitle('firstName', null); $validation->setTitle('lastName', null); $result = $validation->validate(); if (!$result->isSuccess()) { echo $result->getErrors()->join("; "); // Значение является обязательным; Значение является обязательным }
错误
错误消息以 \Fi1a\Validation\Errors
集合表示,可以通过类结果 \Fi1a\Validation\Result
的 getErrors()
方法获取。
use Fi1a\Validation\Validator; $validator = new Validator(); $validation = $validator->make($_POST + $_FILES, [ 'id' => 'required|integer', 'email' => 'required|email', ]); $result = $validation->validate(); if (!$result->isSuccess()) { $errors = $result->getErrors(); // \Fi1a\Validation\Errors echo $errors->firstOfAll()->join('; '); }
\Fi1a\Validation\Errors
集合中可用的方法
firstOfAll()
- 返回字段的第一个错误;allForField()
- 返回特定字段的全部错误;firstOfField()
- 返回特定字段的第一个错误;allForRule()
- 返回特定规则的全部错误;asArray(bool $flat = true)
- 返回错误消息数组(参数 $flat 确定错误消息数组的格式)。
也提供所有 \Fi1a\Collection\Collection
集合的方法。
受影响值
受影响值以 \Fi1a\Validation\ResultValues
集合表示,可以通过类结果 \Fi1a\Validation\Result
的 getValues()
方法获取。
use Fi1a\Validation\Validator; $validator = new Validator(); $validation = $validator->make($_POST + $_FILES, [ 'id' => 'required|integer', 'email' => 'required|email', ]); $result = $validation->validate(); if (!$result->isSuccess()) { $values = $result->getValues(); // \Fi1a\Validation\ResultValues|\Fi1a\Validation\Value[] $values->getInvalid(); // \Fi1a\Validation\ResultValues|\Fi1a\Validation\Value[] $values->getValid(); // \Fi1a\Validation\ResultValues|\Fi1a\Validation\Value[] }
\Fi1a\Validation\ResultValues
集合中可用的方法
getInvalid()
- 未通过验证的值;getValid()
- 成功通过验证的值。
也提供所有 \Fi1a\Collection\Collection
集合的方法。
脚本
场景用于确定应用于当前状态的规则。例如:在创建场景中,密码字段是必填的,而在更新场景中则不是。可以使用场景来实现这一点。
Fi1a.Validation\On
类指定规则链属于哪个场景。
Fi1a.Validation\Validator
类的 make
方法的第五个参数传递当前使用的场景。
use Fi1a\Validation\AllOf; use Fi1a\Validation\On; use Fi1a\Validation\Validator; $validator = new Validator(); $values = [ 'key1' => [1, 2, 3], ]; $rules = [ 'key1' => 'array', new On('key1', AllOf::create()->minCount(1), 'create'), new On('key1', AllOf::create()->minCount(4), 'update'), 'key1:*' => 'required|integer', ]; $validation = $validator->make( $values, $rules, [], [], 'create' ); $result = $validation->validate(); $result->isSuccess(); // true $validation = $validator->make( $values, $rules, [], [], 'update' ); $result = $validation->validate(); $result->isSuccess(); // false
规则集
规则集是一个实现 \Fi1a\Validation\RuleSetInterface
接口的类。
使用规则集类可以定义
- 字段规则;
- 规则所属的场景;
- 字段标题;
- 错误消息。
规则集示例
use Fi1a\Validation\AbstractRuleSet; /** * Набор правил */ class UserRuleSet extends AbstractRuleSet { /** * @inheritDoc */ public function init(): bool { $this->fields('id', 'email', 'tags', 'tags:*:id') ->on('create', 'copy') ->allOf() ->required(); $this->fields('id', 'email', 'tags', 'tags:*:id') ->on('update') ->allOf() ->requiredIfPresence(); $this->fields('id')->allOf()->integer(); $this->fields('email')->allOf()->email(); $this->fields('tags')->allOf()->array(); $this->fields('tags:*:id')->allOf()->numeric(); if ($this->getValue('password')->isPresence() || $this->getScenario() === 'create') { $this->fields('password')->allOf()->required()->minLength(8); $this->fields('confirm_password')->allOf()->required()->same('password'); } return true; } /** * @inheritDoc */ public function getMessages(): array { return array_merge(parent::getMessages(), [ 'tags|required' => 'Укажите хотябы один {{name}}', ]); } /** * @inheritDoc */ public function getTitles(): array { return array_merge(parent::getTitles(), [ 'tags' => 'тег', ]); } }
根据场景 create
使用规则集
use Fi1a\Validation\Validator; $validator = new Validator(); $validation = $validator->make(new UserRuleSet($_POST + $_FILES), [], [], [], 'create'); $result = $validation->validate(); if (!$result->isSuccess()) { echo $result->getErrors()->join("\n"); }
存在性用于验证(检查)
默认情况下,大多数规则在验证(检查)时,如果值不存在(除了 require()
),则返回 true
。实现 Fi1a\Validation\Presence\WhenPresenceInterface
接口的类定义了检查值存在性的标准。
以下类可用
Fi1a\Validation\Presence\WhenPresence
- 根据键的存在性确定值的存在性;Fi1a\Validation\Presence\WhenNotValue
- 根据传递的值确定值是否存在(如果等于认为不存在);Fi1a\Validation\Presence\WhenNotNull
- 根据值是否为 null 确定值是否存在(如果为 null 认为不存在);Fi1a\Validation\Presence\WhenNotIn
- 根据传递的值确定值是否存在(如果包含在值中认为不存在);Fi1a\Validation\Presence\WhenComposite
- 作为其他类检查值存在性的组合使用。
默认情况下使用 Fi1a\Validation\Presence\WhenPresence
类。但您可以传递所需的任何类。
use Fi1a\Validation\AllOf; use Fi1a\Validation\Presence\WhenNotNull; $chain = AllOf::create()->boolean(new WhenNotNull()); $chain->validate(null)->isSuccess(); // true $chain->validate(true)->isSuccess(); // true $chain->validate('not-boolean')->isSuccess(); // false
可以使用 setPresence
方法立即为所有规则设置定义存在性的对象。
use Fi1a\Validation\Presence\WhenNotNull; use Fi1a\Validation\Validator; $validator = new Validator(); $validation = $validator->make( [ 'array' => [null, 2, 3], ], [ 'array' => 'array|minCount(1)', 'array:*' => 'integer', ] ); $validation->setPresence(new WhenNotNull()); $result = $validation->validate(); $result->isSuccess(); // true
规则
alphaNumeric(?WhenPresenceInterface $presence = null)
值必须是字母数字的
use Fi1a\Validation\AllOf; AllOf::create()->alphaNumeric()->validate('123abc')->isSuccess(); // true AllOf::create()->alphaNumeric()->validate('abc 123')->isSuccess(); // false
alpha(?WhenPresenceInterface $presence = null)
值是否仅是字母(不带数字)
use Fi1a\Validation\AllOf; AllOf::create()->alpha()->validate('abc')->isSuccess(); // true AllOf::create()->alpha()->validate('abc100')->isSuccess(); // false
array(?WhenPresenceInterface $presence = null)
值是否是数组
use Fi1a\Validation\AllOf; AllOf::create()->array()->validate([1, 2, 3])->isSuccess(); // true AllOf::create()->array()->validate(false)->isSuccess(); // false
betweenCount(int $min, int $max, ?WhenPresenceInterface $presence = null)
检查数组中的最小和最大元素数量
use Fi1a\Validation\AllOf; AllOf::create()->betweenCount(2, 5)->validate([1, 2, 3])->isSuccess(); // true AllOf::create()->betweenCount(2, 5)->validate(3000000)->isSuccess(); // false AllOf::create()->betweenCount(2, 5)->validate([1,])->isSuccess(); // false
betweenDate(string $minDate, string $maxDate, ?string $format = null, ?WhenPresenceInterface $presence = null)
检查最大和最小日期
use Fi1a\Validation\AllOf; AllOf::create() ->betweenDate('10.10.2022 10:10:10', '12.10.2022 10:10:10') ->validate('11.10.2022 10:10:10') ->isSuccess(); // true AllOf::create() ->betweenDate('10.10.2022 10:10:10', '12.10.2022 10:10:10') ->validate('10.10.2022 09:00:00') ->isSuccess(); // false AllOf::create() ->betweenDate('10.10.2022', '12.10.2022', 'd.m.Y') ->validate('11.10.2022') ->isSuccess(); // true
betweenLength(int $min, int $max, ?WhenPresenceInterface $presence = null)
检查字符串的最大和最小长度
use Fi1a\Validation\AllOf; AllOf::create()->betweenLength(2, 5)->validate(150)->isSuccess(); // true AllOf::create()->betweenLength(2, 5)->validate(3000000)->isSuccess(); // false AllOf::create()->betweenLength(2, 5)->validate('abc def gh')->isSuccess(); // false
between($min, $max, ?WhenPresenceInterface $presence = null)
检查最大和最小值
use Fi1a\Validation\AllOf; AllOf::create()->between(100, 200)->validate(150)->isSuccess(); // true AllOf::create()->between(100, 200)->validate(300)->isSuccess(); // false AllOf::create()->between(100, 200)->validate('abc')->isSuccess(); // false
boolean(?WhenPresenceInterface $presence = null)
值是否是逻辑的
use Fi1a\Validation\AllOf; AllOf::create()->boolean()->validate(true)->isSuccess(); // true AllOf::create()->boolean()->validate(false)->isSuccess(); // true AllOf::create()->boolean()->validate('TRUE')->isSuccess(); // true AllOf::create()->boolean()->validate('FALSE')->isSuccess(); // true AllOf::create()->boolean()->validate('0')->isSuccess(); // true AllOf::create()->boolean()->validate('1')->isSuccess(); // true AllOf::create()->boolean()->validate(0)->isSuccess(); // true AllOf::create()->boolean()->validate(1)->isSuccess(); // true AllOf::create()->boolean()->validate('Y')->isSuccess(); // true AllOf::create()->boolean()->validate('N')->isSuccess(); // true AllOf::create()->boolean()->validate(100)->isSuccess(); // false AllOf::create()->boolean()->validate('abc')->isSuccess(); // false
date(string $format = null, ?WhenPresenceInterface $presence = null)
检查日期格式
use Fi1a\Validation\AllOf; AllOf::create()->date()->validate('10.10.2022')->isSuccess(); // true AllOf::create()->date('d')->validate('10.10.2022')->isSuccess(); // false AllOf::create()->date('d m, Y')->validate('10 10, 2022')->isSuccess(); // true AllOf::create()->date()->validate('abc')->isSuccess(); // false
email(?WhenPresenceInterface $presence = null)
值是否是电子邮件地址
use Fi1a\Validation\AllOf; AllOf::create()->email()->validate('foo@bar.ru')->isSuccess(); // true AllOf::create()->email()->validate('foo')->isSuccess(); // false
equalDate(string $equalDate, ?string $format = null, ?WhenPresenceInterface $presence = null)
检查日期是否相等
use Fi1a\Validation\AllOf; AllOf::create()->equalDate('10.10.2022 10:10:10')->validate('10.10.2022 10:10:10')->isSuccess(); // true AllOf::create()->equalDate('10.10.2022 10:10:10')->validate('10.10.2022 09:00:00')->isSuccess(); // false AllOf::create()->equalDate('10.10.2022', 'd.m.Y')->validate('10.10.2022')->isSuccess(); // true
equal(float $equal, ?WhenPresenceInterface $presence = null)
检查数字是否相等
use Fi1a\Validation\AllOf; AllOf::create()->equal(100)->validate(100)->isSuccess(); // true AllOf::create()->equal(100)->validate(200)->isSuccess(); // false
fileSize(string $min, string $max, ?WhenPresenceInterface $presence = null)
上传文件的尺寸。
尺寸指示器
- B - 字节;
- KB, K - 千字节;
- MB, M - 兆字节;
- GB, G - 吉字节;
- TB, T - 太字节;
- PB, P - 赛字节。
use Fi1a\Validation\Validator; $validator = new Validator(); $validation = $validator->make($_POST + $_FILES, [ 'photo' => 'required|fileSize("0", "1MB")', ]); $result = $validation->validate(); if (!$result->isSuccess()) { echo $result->getErrors()->join("\n"); }
generic(array $rules, array $messages = [], array $titles = [], ?WhenPresenceInterface $presence = null)
嵌套规则
use Fi1a\Validation\Validator; $validator = new Validator(); $validation = $validator->make( [ 'columns' => [ [ 'foo' => null, ], [ 'foo' => [ 'bar' => 'baz' ], ], ], ], [ 'columns' => AllOf::create()->array(), 'columns:*:foo' => AllOf::create()->generic(['bar' => 'required']), ] ); $validation->validate()->isSuccess(); // true $validator = new Validator(); $validation = $validator->make( [ 'columns' => [ [ 'foo' => [], ], [ 'foo' => [ 'bar' => 'baz' ], ], ], ], [ 'columns' => AllOf::create()->array(), 'columns:*:foo' => AllOf::create()->generic(['bar' => 'required']), ] ); $validation->validate()->isSuccess(); // false
url(?WhenPresenceInterface $presence = null)
验证 URL 地址
use Fi1a\Validation\AllOf; AllOf::create()->url()->validate('https://domain.ru/path/')->isSuccess(); // true AllOf::create()->url()->validate('https')->isSuccess(); // false
in($presence, ...$in)
可接受值(非严格值检查)
use Fi1a\Validation\AllOf; AllOf::create()->in(1, 2, 3)->validate(1)->isSuccess(); // true AllOf::create()->in(1, 2, 3)->validate(100.1)->isSuccess(); // false AllOf::create()->in('camelCase', 'UPPERCASE')->validate('uppercase')->isSuccess(); // true
integer(?WhenPresenceInterface $presence = null)
值是否是整数
use Fi1a\Validation\AllOf; AllOf::create()->integer()->validate(1)->isSuccess(); // true AllOf::create()->integer()->validate(100.1)->isSuccess(); // false
json(?WhenPresenceInterface $presence = null)
json是否为一维数组
use Fi1a\Validation\AllOf; AllOf::create()->json()->validate(json_encode([1, 2, 3]))->isSuccess(); // true AllOf::create()->json()->validate('{')->isSuccess(); // false
maxCount(int $max, ?WhenPresenceInterface $presence = null)
检查数组中最大元素数量
use Fi1a\Validation\AllOf; AllOf::create()->maxCount(2)->validate([1,])->isSuccess(); // true AllOf::create()->maxCount(2)->validate(100)->isSuccess(); // false AllOf::create()->maxCount(2)->validate([1, 2, 3])->isSuccess(); // false
maxDate(string $maxDate, ?string $format = null, ?WhenPresenceInterface $presence = null)
检查最大日期
use Fi1a\Validation\AllOf; AllOf::create()->maxDate('10.10.2022 11:10:10')->validate('10.10.2022 10:10:10')->isSuccess(); // true AllOf::create()->maxDate('10.10.2022 10:10:10')->validate('10.10.2022 12:00:00')->isSuccess(); // false AllOf::create()->maxDate('10.10.2022', 'd.m.Y')->validate('09.10.2022')->isSuccess(); // true
maxLength(int $max, ?WhenPresenceInterface $presence = null)
检查字符串最大长度
use Fi1a\Validation\AllOf; AllOf::create()->maxLength(5)->validate('123')->isSuccess(); // true AllOf::create()->maxLength(5)->validate(123)->isSuccess(); // true AllOf::create()->maxLength(5)->validate(1000000)->isSuccess(); // false AllOf::create()->maxLength(5)->validate('abc def h')->isSuccess(); // false
max($max, ?WhenPresenceInterface $presence = null)
检查最大值
use Fi1a\Validation\AllOf; AllOf::create()->max(100)->validate(50)->isSuccess(); // true AllOf::create()->max(200)->validate(300)->isSuccess(); // false AllOf::create()->max(200)->validate('abc')->isSuccess(); // false
mime(WhenPresenceInterface|string $presence, string ...$extensions)
上传文件类型
use Fi1a\Validation\Validator; $validator = new Validator(); $validation = $validator->make($_POST + $_FILES, [ 'photo' => 'fileSize("0", "1MB")|mime("jpeg", "png")', ]); $result = $validation->validate(); if (!$result->isSuccess()) { echo $result->getErrors()->join("\n"); }
minCount(int $min, ?WhenPresenceInterface $presence = null)
检查数组中最小元素数量
use Fi1a\Validation\AllOf; AllOf::create()->minCount(2)->validate([1, 2, 3])->isSuccess(); // true AllOf::create()->minCount(2)->validate(100)->isSuccess(); // false AllOf::create()->minCount(2)->validate([1])->isSuccess(); // false
minDate(string $minDate, ?string $format = null, ?WhenPresenceInterface $presence = null)
检查最小日期
use Fi1a\Validation\AllOf; AllOf::create()->minDate('10.10.2022 10:10:10')->validate('10.10.2022 10:10:10')->isSuccess(); // true AllOf::create()->minDate('10.10.2022 10:10:10')->validate('10.10.2022 09:00:00')->isSuccess(); // false AllOf::create()->minDate('10.10.2022', 'd.m.Y')->validate('10.10.2022')->isSuccess(); // true
minLength(int $min, ?WhenPresenceInterface $presence = null)
检查字符串最小长度
use Fi1a\Validation\AllOf; AllOf::create()->minLength(5)->validate('123456')->isSuccess(); // true AllOf::create()->minLength(5)->validate(123456)->isSuccess(); // true AllOf::create()->minLength(5)->validate(100)->isSuccess(); // false AllOf::create()->minLength(5)->validate('abc')->isSuccess(); // false
min($min, ?WhenPresenceInterface $presence = null)
检查最小值
use Fi1a\Validation\AllOf; AllOf::create()->min(100)->validate(200)->isSuccess(); // true AllOf::create()->min(200)->validate(100)->isSuccess(); // false AllOf::create()->min(200)->validate('abc')->isSuccess(); // false
notIn($presence, ...$notIn)
不允许的值(非严格值检查)
use Fi1a\Validation\AllOf; AllOf::create()->notIn(1, 2, 3)->validate(4)->isSuccess(); // true AllOf::create()->notIn(1, 2, 3)->validate(2)->isSuccess(); // false AllOf::create()->notIn('camelCase', 'UPPERCASE')->validate('uppercase')->isSuccess(); // false
null(?WhenPresenceInterface $presence = null)
值是否为null
use Fi1a\Validation\AllOf; AllOf::create()->null()->validate(null)->isSuccess(); // true AllOf::create()->null()->validate(false)->isSuccess(); // false
numeric(?WhenPresenceInterface $presence = null)
值是否为数字
use Fi1a\Validation\AllOf; AllOf::create()->numeric()->validate(1)->isSuccess(); // true AllOf::create()->numeric()->validate(false)->isSuccess(); // false
regex(string $regex, ?WhenPresenceInterface $presence = null)
正则表达式检查
use Fi1a\Validation\AllOf; AllOf::create()->regex('/[0-9]/mui')->validate(200)->isSuccess(); // true AllOf::create()->regex('/[0-9]/mui')->validate('abc')->isSuccess(); // false
requiredIfPresence(?WhenPresenceInterface $presence = null)
如果存在,则为必填项
use Fi1a\Validation\Validator; $validator = new Validator(); $validation = $validator->make(['foo' => true], ['foo' => 'requiredIfPresence']); $validation->validate()->isSuccess(); // true $validation->setValues(['foo' => null]); $validation->validate()->isSuccess(); // false $validation->setValues([]); $validation->validate()->isSuccess(); // true
required()
必填项
use Fi1a\Validation\AllOf; AllOf::create()->required()->validate(true)->isSuccess(); // true AllOf::create()->required()->validate(null)->isSuccess(); // false
requiredWith(string ...$fieldNames)
如果有值,则为必填项
use Fi1a\Validation\AllOf; AllOf::create() ->requiredWith('array:foo', 'array:bar') ->validate(['array' => ['foo' => 'foo', 'bar' => 'bar'], 'baz' => 'baz'], 'baz') ->isSuccess(); // true AllOf::create() ->requiredWith('array:foo', 'array:bar') ->validate(['array' => ['foo' => 'foo', 'bar' => null], 'baz' => null], 'baz') ->isSuccess(); // true AllOf::create() ->requiredWith('array:foo', 'array:bar') ->validate(['array' => ['foo' => 'foo', 'bar' => 'bar'], 'baz' => null], 'baz') ->isSuccess(); // false
same(string $fieldName, ?WhenPresenceInterface $presence = null)
值是否与指定字段值相同
use Fi1a\Validation\AllOf; AllOf::create()->same('field1')->validate(200)->isSuccess(); // false AllOf::create()->same('bar')->validate(['foo' => 200, 'bar' => 200], 'foo')->isSuccess(); // true
strictIn($presence, ...$in)
允许的值(严格值检查)
use Fi1a\Validation\AllOf; AllOf::create()->strictIn(1, 2, 3)->validate(1)->isSuccess(); // true AllOf::create()->strictIn(1, 2, 3)->validate(100.1)->isSuccess(); // false AllOf::create()->strictIn('camelCase', 'UPPERCASE')->validate('uppercase')->isSuccess(); // false
strictNotIn($presence, ...$notIn)
不允许的值(严格值检查)
use Fi1a\Validation\AllOf; AllOf::create()->strictNotIn(1, 2, 3)->validate(4)->isSuccess(); // true AllOf::create()->strictNotIn(1, 2, 3)->validate(2)->isSuccess(); // false AllOf::create()->strictNotIn('camelCase', 'UPPERCASE')->validate('uppercase')->isSuccess(); // true
string(?WhenPresenceInterface $presence = null)
值是否为字符串
use Fi1a\Validation\AllOf; AllOf::create()->string()->validate('foo')->isSuccess(); // true AllOf::create()->string()->validate(false)->isSuccess(); // false
自定义规则检查
库提供了扩展可用规则检查的功能。规则检查必须实现接口\Fi1a\Validation\Rule\RuleInterface
。
自定义规则检查的示例实现
use \Fi1a\Validation\Rule\AbstractRule; use \Fi1a\Validation\ValueInterface; /** * Проверка на уникальное значение */ class UniqueRule extends AbstractRule { /** * @var Bitrix\Main\ORM\Data\DataManager */ private $className; /** * @var string */ private $column; /** * @var int|null */ private $notId; /** * Конструктор */ public function __construct(string $className, string $column, ?int $notId = null, ?WhenPresenceInterface $presence = null) { $this->className = $className; $this->column = $column; $this->notId = $notId; parent::__construct($presence); } /** * @inheritDoc */ public function validate(ValueInterface $value): bool { if (!$value->isPresence()) { return true; } $filter = [ $this->column => $value->getValue(), ]; if ($this->notId) { $filter['!ID'] = $this->notId; } $success = $this->className::getCount($filter) === 0; if (!$success) { $this->addMessage('Значение {{if(name)}}"{{name}}" {{endif}}не является уникальным', 'unique'); } return $success; } /** * @inheritDoc */ public static function getRuleName(): string { return 'unique'; } }
使用方法addRule
在验证器类中注册自定义规则
\Fi1a\Validation\Validator::addRule(UniqueRule::class);
然后可以使用自定义规则检查
use \Fi1a\Validation\AllOf; use \Bitrix\Main\UserTable; $unique = AllOf::create()->unique(UserTable::class, 'LOGIN'); $unique->validate('admin')->isSuccess(); // false $unique->validate('user')->isSuccess(); // true