fi1a/validation

PHP 表单值和数据的验证(检查)

3.2.1 2023-03-11 01:41 UTC

This package is auto-updated.

Last update: 2024-09-11 04:47:15 UTC


README

Latest Version Software License PHP Version Coverage Status Total Downloads Support mail

验证意味着检查用户填写的数据。此包提供了在表单数据提交后对服务器端进行检查的机会。

功能

  • 检查(验证)数组和单独值的验证;
  • 检查(验证)表单值和上传文件的验证;
  • 支持带有脚本的规则集;
  • 可以更改字段名称;
  • 可以更改错误文本;
  • 可以扩展自定义验证规则;
  • 脚本和规则集;
  • 检查公共字段的对象。

安装

可以使用 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 方法传递包含错误消息的数组,或者稍后通过 setMessagesetMessages 方法对象来设置错误消息。也可以在规则集中定义错误消息 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 方法传递标题,或者稍后通过 setTitlesetTitles 方法对象来设置标题。也可以在规则集中定义标题 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\ResultgetErrors() 方法获取。

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\ResultgetValues() 方法获取。

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