krak/validation

功能验证库

v0.3.11 2018-08-05 10:29 UTC

This package is auto-updated.

Last update: 2024-09-18 17:17:24 UTC


README

Krak Validation 库是一种功能性和简单的验证方法和接口。它源于对简单接口和配置的验证库的需求。其他主流验证器,如 Respect、Zend 或 Symfony,在它们的 API 中有很多复杂性,添加实际的验证器可能需要添加几个类。

Krak Validation 通过采用功能性的验证方法来改变这一切,其中每个验证器只是一个函数或 Krak\Validation\Validator 的实例。这种设计很容易进行扩展、自定义验证器和装饰器。它附带了一个 Krak\Validation\Kernel,用于管理验证器,提供一个简单、流畅和可定制的接口来利用验证器。

安装

使用 composer 在 krak/validation 中安装

用法

<?php

$validation = new Krak\Validation\Kernel();
$validator = $validation->make([
    'name' => 'required|string',
    'age' => 'optional|integer|between:18,25',
]);
$violations = $validator->validate([
    'name' => 'RJ',
    'age' => 17,
]);

if ($violations) { // you can also check $validator->failed()
    print_r($violations->format()); // format into an array of error messages
}

这将打印类似以下内容

Array
(
    [age] => Array
        (
            [0] => The Age field must be between 18 and 25
        )

)

验证器

验证器可以是 Krak\Validation\Validator,或任何接受值并在成功时返回 null、在失败时返回违规的可调用对象。

验证器实现以下签名

function($value, array $ctx = [])

第二个参数通常可以省略,但用于将附加信息传递给验证器。一个好的例子是 PSR 容器,以便在实际验证时延迟加载依赖项。

违规

使用 violateviolations 函数创建违规很容易。对于大多数验证器,你只需创建一个违规即可。

<?php

use Krak\Validation;

/** enforces that a value equals a specific value */
function equalsStringValidator($match) {
    return function($value, array $ctx = []) use ($match) {
        if ($value == $match) {
            return;
        }

        return Validation\violate('equals_string', [
            'match' => $match
        ]);
    };
}

$v = equalsStringValidator('foo');
$v('foo'); // returns null
$violation = $v('bar'); // return a Krak\Validation\Violation

在某些情况下,一个验证器可以返回多个违规。在这种情况下,我们只需使用 violations 来创建违规集合。你可以查看 Krak\Validation\Validators\collection 验证器来了解如何创建违规集合。

抛出违规

一旦你有了违规或违规集合,你可以选择将它们抛出为异常以在流上游处理。

<?php

try {
    $violation->abort();
} catch (Krak\Validation\Exception\ViolationException $e) {
    assert($e->violation === $violation);
}

断言数据

一个非常常见的做法是使用验证内核来创建和验证域数据,如果发生任何违规,则抛出 ViolationException。这可以通过简单的 assert 方法完成。

$validation = new Krak\Validation\Kernel();
$validation->make([
    'name' => 'required|string',
    'age' => 'optional|integer|between:18,25',
])->assert(['name' => 'RJ', 'age' => 100]);
// this will have thrown a ViolationException due to the age constraint

然后你可以轻松地捕获流上游的 ViolationException 并将违规格式化为可读的错误。

try {
    return response($storeUser($userData), 201);
} catch (Krak\Validation\Exception\ViolationException $e) {
    return response([
        'errors' => $e->violation->format(),
    ], 422);
}

验证包

验证包是对 Validation\Kernel 的简单扩展,它将验证器和消息注册到系统中。

创建验证包

要创建验证包,你需要扩展 ValidationPackage 接口。

interface ValidationPackage
{
    public function withValidation(Kernel $validation);
}

从那里,你可以以任何你需要的方式配置验证内核。

通常,你只需使用 validatorsmessagesaliases 方法添加带键的验证和相应的函数或别名。

一个示例验证包可能如下所示

<?php

use Krak\Validation;

class AcmeValidationPackage implements Validation\ValidationPackage
{
    public function withValidation(Validation\Kernel $v) {
        $v->validators([
            'integer' => 'intValidator', // name of intValidator func
            'min' => MinValidator::class // name of MinValidator class
        ]);
        $v->messages([
            'integer' => 'The {{attribute}} is not a valid integer',
            'min' => 'The {{attribute}} size must be greater than or equal to {{min}}',
        ]);
        $v->aliases([
            'int' => 'integer',
        ]);
    }
}

验证器将定义在不同的文件中,如下所示

use Krak\Validation;

// intValidator.php
function intValidator() {
    return function($v) {
        return !is_int($v) ? Validation\violate('integer') : null;
    };
}

// MinValidator.php
class MinValidator implements Validation\Validator
{
    private $min;

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

    public function validate($value, array $context = []) {
        return $value < $min ? Validation\violate('min', ['min' => $this->min]) : null;
    }
}

核心验证包

核心验证包定义了许多有用的验证器。

all

使用给定的验证器验证数组。如果数组中的任何元素未通过验证,则返回违规。

定义: Krak\Validation\Validators\forAll($validator)

简单用法

$validator->make('all:integer')->validate([1,2,3]);

高级用法

use function Krak\Validation\Validators\{forAll};
$validator->make(forAll('integer|between:1,3'))->validate([1,2,3])

独立用法

use function Krak\Validation\Validators\{forAll, typeInteger};

forAll(typeInteger())([2,3]);

alpha

包装 ctype_alpha 函数并验证字符串以验证仅包含字母字符。

定义: Krak\Validation\Validators\alpha()

简单用法

$validator->make('alpha')->validate('abc');

独立用法

use function Krak\Validation\Validators\{alpha};

alpha()('123');

字母数字

封装了 ctype_alnum 函数,用于验证字符串是否为字母数字。

定义: Krak\Validation\Validators\alphaNum()

简单用法

$validator->make('alpah_num')->validate('abc123');

独立用法

use function Krak\Validation\Validators\{alphaNum};
alphaNum()('abc123');

数组

使用 is_array 函数验证值是否为数组。

定义: Krak\Validation\Validators\typeArray()

简单用法

$validator->make('array')->validate();

独立用法

use function Krak\Validation\Validators\{typeArray};

typeArray()([]);

介于

验证一个值的 大小 在两个值之间(包括两个值)。

定义: Krak\Validation\Validators\between($min, $max)

简单用法

$validator->make('between:1,2')->validate(2);

独立用法

use function Krak\Validation\Validators\{between};

between(1, 2)(2);

布尔值

验证值是否为布尔值。 truefalse"0""1"01 都是布尔值的实例。

定义: Krak\Validation\Validators\typeBoolean()

简单用法

$validator->make('boolean')->validate(true);

独立用法

use function Krak\Validation\Validators\{typeBoolean};

typeBoolean()(true);

日期

使用 strototime 验证字符串是否为有效日期。接受 strtotime 所接受的任何内容。

定义: Krak\Validation\Validators\date()

简单用法

$validator->make('date')->validate('2017-08-11');

独立用法

use function Krak\Validation\Validators\{date};

date()('2017-08-11');

数字

使用 ctype_digits 函数验证字符串是否为数字类型。

定义: Krak\Validation\Validators\digits()

简单用法

$validator->make('digits')->validate('123');

独立用法

use function Krak\Validation\Validators\{digits};

digits()('123');

双精度浮点数

使用 is_double 验证值是否为双精度浮点数。

定义: Krak\Validation\Validators\double()

简单用法

$validator->make('double')->validate(4.2);

独立用法

use function Krak\Validation\Validators\{double};

double()(4.2);

电子邮件

验证字符串是否符合电子邮件正则表达式。

定义: Krak\Validation\Validators\regexEmail()

简单用法

$validator->make('email')->validate('username@gmail.com');

独立用法

use function Krak\Validation\Validators\{regexEmail};

regexEmail()('username@gmail.com');

存在

required 的别名。

浮点数

使用 is_float 验证值是否为浮点数。

定义: Krak\Validation\Validators\float()

简单用法

$validator->make('float')->validate(4.2);

独立用法

use function Krak\Validation\Validators\{float};

float()(4.2);

在...之内

验证值是否在给定的数组内。

定义: Krak\Validation\Validators\inArray

简单用法

$validator->make('in:a,b,c')->validate('b');

独立用法

use function Krak\Validation\Validators\{inArray};

inArray(['a', 'b', 'c'])('b');

整数

验证值是否为整数。

定义: Krak\Validation\Validators\typeInteger()

简单用法

$validator->make('integer')->validate(1);

独立用法

use function Krak\Validation\Validators\{typeInteger};

typeInteger()(1);

长度

验证值的大小 是否等于 给定长度。

定义: Krak\Validation\Validators\length($size)

简单用法

$validator->make('length:3')->validate('abc');

独立用法

use function Krak\Validation\Validators\{length};

length()('abc');

最大值

验证值的大小 是否小于或等于 给定的最大值。

定义: Krak\Validation\Validators\max($max)

简单用法

$validator->make('max:5')->validate(4);

独立用法

use function Krak\Validation\Validators\{max};

max(5)(4);

最小值

验证值的大小 是否大于或等于 给定的最小值。

定义: Krak\Validation\Validators\min($min)

简单用法

$validator->make('min:2')->validate(3);

独立用法

use function Krak\Validation\Validators\{min};

min(2)(3);

空值

验证值的数据类型为空。

定义: Krak\Validation\Validators\typeNull()

简单用法

$validator->make('null')->validate(null);

独立用法

use function Krak\Validation\Validators\{typeNull};

typeNull()(null);

可空

验证类型是否为空或非空。这通常用于验证器链中,如果值为空则停止验证,否则继续验证。

定义: Krak\Validation\Validators\nullable()

简单用法

$v = $validator->make('nullable|integer');
$v->validate(null);
$v->validate(1);

独立用法

use function Krak\Validation\Validators\{pipe, nullable, typeInteger};

$v = pipe([nullable(), typeInteger()]);
$v(null);
$v(1);

数字

验证给定的值是浮点数、双精度浮点数或整数。这不同于 is_numeric

定义: Krak\Validation\Validators\number()

简单用法

$validator->make('number')->validate(1);

独立用法

use function Krak\Validation\Validators\{number};

number()(1);

数值

使用 is_numeric 函数验证给定的值是否为数值。

定义: Krak\Validation\Validators\typeNumeric()

简单用法

$validator->make('numeric')->validate('1.5');

独立用法

use function Krak\Validation\Validators\{typeNumeric};

typeNumeric()('1.5');

可选

验证键数组是可选的,不必在数组中存在。这个验证器只在集合的上下文中才有意义。

定义: Krak\Validation\Validators\optional()

简单用法

$v = $validator->make([
    'id' => 'optional|integer'
]);
$v->validate([]);
$v->validate(['id' => 1])

独立用法

use function Krak\Validation\Validators\{collection, optional, typeInteger, pipe};

$v = collection([
    'id' => pipe([optional(), typeInteger()])
]);
$v([]);
$v(['id' => 1]);

正则表达式

验证给定的值是浮点数、双精度浮点数或整数。这不同于 is_numeric

定义: Krak\Validation\Validators\regexMatch($regex, $exclude = false)

简单用法

$validator->make('regex:/a+b/')->validate('aaab');

注意 由于验证规则解析器如何验证 |:,,通过字符串定义正则表达式可能很棘手。你几乎总是想调用实际的验证器本身。

高级用法

use function Krak\Validation\Validators\{regexMatch};

$validator->make(regexMatch('/(aa|bb)/'))->validate('aa');

独立用法

use function Krak\Validation\Validators\{regexMatch};

regexMatch('/(aa|bb)/')('aa');

正则表达式排除

regex 相同,但匹配的是排除特定正则表达式的值。

定义: Krak\Validation\Validators\regexExclude($regex)

简单用法

$validator->make('regex:/a+b/')->validate('c');

注意 由于验证规则解析器如何验证 |:,,通过字符串定义正则表达式可能很棘手。你几乎总是想调用实际的验证器本身。

高级用法

use function Krak\Validation\Validators\{regexExclude};

$validator->make(regexExclude('/(aa|bb)/'))->validate('cc');

独立用法

use function Krak\Validation\Validators\{regexExclude};

regexExclude('/(aa|bb)/')('cc');

必需

验证给定值是否在一个集合中是必需的。此验证器仅在集合的上下文中才有意义。

定义: Krak\Validation\Validators\required()

简单用法

$validator->make([
    'id' => 'required|integer',
])->validate(['id' => 1]);

独立用法

use function Krak\Validation\Validators\{collection, pipe, typeInteger, required};

collection([
    'id' => pipe([required(), typeInteger()])
])(['id' => 1]);

字符串

验证给定值是否为字符串。

定义: Krak\Validation\Validators\typeString()

简单用法

$validator->make('string')->validate('a');

独立用法

use function Krak\Validation\Validators\{typeString};

typeString()('a');

Doctrine 验证包

Doctrine 验证包定义了与 doctrine 相关的验证器。

要启用 doctrine 包,你可以执行以下操作

$validation = new Krak\Validation\Kernel();
$validation->withDoctrineValidators();
// only needed for doctrine_entities, doctrine_entity, and doctrine_unique_entity
$validation['Doctrine\Common\Persistence\ObjectManager'] = function() {
    // return a configured entity manager here...
};
$validation['Doctrine\DBAL\Connection'] = function() {
    // return a dbal connection here
};
$validation->context([
    'doctrine.model_prefix' => Acme\Model::class,
]);

doctrine_all_exist

验证一组字符串或整数是否在给定表中都存在。

定义: class Krak\Validation\Validators\Doctrine\AllExist($table_name, $field = 'id', $type = 'int')

简单用法

$validator->make('array|all:integer|doctrine_all_exist:users')->validate([1,2,3]);

独立用法

use Krak\Validation\Validators\Doctrine\AllExist;
use function Krak\Validation\Validators\{pipe, typeInteger, forAll};

pipe([forAll(typeInteger), new AllExist('users')])([1,2,3]);

doctrine_entities

验证一组 ORM 实体是否从唯一键存在。如果提供了实体名称,则与 doctrine.model_prefix 连接。

定义: class Krak\Validation\Validators\Doctrine\Entities($entity_name, $field = 'id')

简单用法

$validator->make('array|all:integer|doctrine_entities:User')->validate([1,2,3]);

独立用法

use Krak\Validation\Validators\Doctrine\Entities;
use function Krak\Validation\Validators\{pipe, typeInteger, forAll};

pipe([forAll(typeInteger), new Entities('User')])([1,2,3]);

doctrine_entity

验证实体是否在数据库中存在,具有给定的值。

定义: class Krak\Validation\Validators\Doctrine\Entity($entity_name, $field = 'id')

简单用法

$validator->make('doctrine_entity:User')->validate(1);

独立用法

use Krak\Validation\Validators\Doctrine\Entity;

(new Entity('User'))->validate(1);

doctrine_exists

验证给定值是否在表的某个字段中存在。

定义: class Krak\Validation\Validators\Doctrine\Exists($table_name, $field = 'id')

简单用法

$validator->make('doctrine_entity:users')->validate(5);

独立用法

use Krak\Validation\Validators\Doctrine\Exists;

(new Exists('users'))->validate(5);

doctrine_unique

验证给定值是否唯一,且在表的字段中不存在。

定义: class Krak\Validation\Validators\Doctrine\Unique($table_name, $field = 'id')

简单用法

$validator->make('doctrine_unique:users,email')->validate('username@gmail.com');

独立用法

use Krak\Validation\Validators\Doctrine\Unique;

(new Unique('users', 'email'))->validate('username@gmail.com');

doctrine_unique_entity

验证给定值是否在表的某个字段中存在。

定义: class Krak\Validation\Validators\Doctrine\UniqueEntity($entity_name, $field = 'id')

简单用法

$validator->make('doctrine_unique_entity:User,email')->validate('username@gmail.com');

独立用法

use Krak\Validation\Validators\Doctrine\UniqueEntity;

(new UniqueEntity('User', 'email'))->validate('username@gmail.com');

API

以下所有内容都在 Krak\Validation\Validators 命名空间中定义。

collection($validators, $err_on_extra = true)

验证具有属性名称映射到其他验证器的验证器映射。 $err_on_extra 是一个标志,用于确定是否验证输入数组中的额外字段。

此函数将根据输入值返回一个 Violation、ViolationCollection 或 null。

toSize($value)

获取变量的长度。如果为字符串,则返回字符串长度。如果为数组,则返回计数。否则,假设为数值并返回其值本身。