iqomp/validator

简单易用的表单/对象验证器

2.3.3 2021-11-17 05:47 UTC

This package is auto-updated.

Last update: 2024-09-17 11:51:09 UTC


README

简单易用的表单/对象验证器。此模块提供两个可用的类用于验证,一个是 Iqomp\Validator\Validator,它可以用来验证对象与数组中的规则列表。第二个类是 Iqomp\Validator\Form,它不接收任何内容(可选用户生成的对象进行验证),验证规则从私有配置中获取。验证器类不仅执行验证,还可以应用过滤器到对象的属性来修改它。

安装

composer require iqomp/validator

发布配置

php bin/hyperf.php vendor:publish iqomp/validator

验证器

Iqomp\Validator\Validator 可以用来验证具有开发者定义的验证规则的对象。

use Iqomp\Validator\Validator;

$rules = [
    'name' => [
        'rules' => [
            'required' => true
        ],
        'filters' => [
            'string' => true
        ]
    ]
];
$object= (object)['name' => 'User'];
list($result, $errors) = Validator::validate($rules, $object);

结果 $result 是一个对象,只包含从 $object 中获取的属性,前提是这些属性在 $rules 中定义了规则。

stdClass Object
(
    [name] => User
)

结果 $errors 是一个错误数组,包含了验证后存在的错误或空数组(如果没有错误)。

Array
(
    [name] => stdClass Object
        (
            [field] => name
            [code] => 11.0
            [text] => This field is required
            [options] => Array
                (
                    [rules] => Array
                        (
                            [required] => 1
                        )

                    [filters] => Array
                        (
                            [string] => 1
                        )

                )

        )

)

方法

static getErrorFormatter(): string

获取当前自定义错误格式化器

static setErrorFormatter(string $formatter): void

设置自定义错误格式化器。

static function validate(array $rules, object $object): array

验证对象与规则列表。此操作将返回一个包含两个成员的数组,第一个是验证后的对象,第二个是存在的错误列表或如果没有错误则为空数组。

验证器规则

这是本模块定义的所有验证器规则。

array => true | assoc | indexed

确保值是一个数组,可选的验证器可以验证它是否是一个关联数组或索引数组。

    // ...
    'rules' => [
        'array' => true // 'assoc', 'indexed'
    ]
    // ...

boolean|bool => true

确保值是布尔值,可以是 falsetrue。其他情况将使验证器失败。

    // ...
    'rules' => [
        'boolean' => true
    ]
    // ....

callback => Class::method

使用外部类验证值。规则的值应该是处理该类的类和方法。

    // ...
    'rules' => [
        'callback' => 'Namespace\\Class::method'
    ]
    // ...

回调应该返回一个索引数组,格式为 [:code, :params, :text]。其中 :code 是错误代码,:params 是根据错误代码发送到翻译的参数列表,:text 是最终要使用的错误消息。如果定义了 :text,则只翻译 :code

date => {format,min-field,min,max-field,max}

确保值是根据提供的格式已知的日期。它可以与 minmax 日期验证。也可以从其他对象字段获取 minmax

    // ...
    'rules' => [
        'date' => [
            'format' => 'Y-m-d',
            'min' => 'now',
            // 'min-field' => 'date-start',
            'max' => '+12 days',
            // 'max-field' => 'date-end'
        ]
    ]
    // ...

email => true

确保值是有效的电子邮件。

    // ...
    'rules' => [
        'email' => true
    ]
    // ...

empty => false

确保值不是空的(伪)。此规则将 null 设置为有效。与 required 规则一起使用,以确保它被提交且不是伪。

    // ...
    'rules' => [
        'empty' => false
    ]
    // ...

equals_to => field

确保值等于其他对象的属性值。它可以用于更改密码动作中的 new-password 字段。

    // ...
    'rules' => [
        'equals_to' => 'new-password'
    ]
    // ...

file => true

确保字段是 _FILES 属性。

    // ...
    'rules' => [
        'file' => true
    ]
    // ...

in => []

确保值是定义的列表之一。

    // ...
    'rules' => [
        'in' => ['one','two','three']
    ]
    // ...

ip => true | 4 | 6

确保值是有效的 IP 地址。可选地,它还可以验证 IPv4 或 IPv6。

    // ...
    'rules' => [
        'ip' => true // '4' | '6'
    ]
    // ...

json => true

确保值是有效的 JSON 字符串。它期望一个 string

    // ...
    'rules' => [
        'json' => true
    ]
    // ...

length => {min,max}

确保值的长度在可接受的范围内。值期望一个字符串或一个数组。规则属性 maxmin 中应该定义一个。

    // ...
    'rules' => [
        'length' => [
            'min' => 1,
            'max' => 12
        ]
    ]
    // ...

notin => []

确保值不是定义的列表之一。

    // ...
    'rules' => [
        'notin' => ['one','two','three']
    ]
    // ...

numeric => true | {min,max}

确保值是数字。可选地传入选项 min 和或 max

    // ...
    'rules' => [
        // 'numeric' => true,
        'numeric' => [
            'min' => 1,
            'max' => 12
        ]
    ]
    // ...

object => true

确保值是一个对象。

    // ...
    'rules' => [
        'object' => true
    ]
    // ...

regex => '!x!'

测试字符串值是否与正则表达式匹配。

    // ...
    'rules' => [
        'regex' => '![0-9]+!'
    ]
    // ...

required => true

确保值存在且不为null。

    // ...
    'rules' => [
        'required' => true
    ]
    // ...

req_on => {field=>{operator,expected}}

仅在条件匹配的情况下确保属性存在且不为null。此规则要求为每个其他字段存在参数 operatorexpected

operator 的值可以是以下之一:=!=><<=>=in!in

    // ...
    'rules' => [
        'req_on' => [
            'other_field' => [
                'operator' => '=',
                'expected' => 12
            ],
            'more_field' => [
                'operator' => 'in',
                'expected' => ['one','two','three']
            ]
        ]
    ]
    // ...

上述规则确保 object->other_field 的值等于 12 AND object->more_field 的值是 onetwothree 中的一个。当前字段仅在两个条件都匹配的情况下是必需的。

text => true | slug | alnumdash | alpha | alnum

确保值是文本。可选地遵循接受的字符。

  1. true 仅验证值的类型为字符串
  2. slug 只接受字符 ^[a-z0-9-_]+$
  3. alnumdash 只接受字符 ^[a-zA-Z0-9-]+$
  4. alpha 只接受字符 ^[a-zA-Z]+$
  5. alnum 只接受字符 ^[a-zA-Z0-9]+$
  6. !regex! 仅在值与提供的正则表达式匹配时接受
    // ...
    'rules' => [
        'text' => true,
        // 'text' => 'slug',
        // 'text' => '!^TR-[0-9]+$!'
    ]
    // ...

url => true | { path, query => true | [] }

确保值是有效的URL,可选地带有路径和一些查询字符串。

    // ...
    'rules' => [
        'url' => true,
        'url' => [
            'path' => true,
            'query' => true,
            'query' => ['page','rpp','q']
        ]
    ]
    // ...

验证器过滤器

array => true

将值转换为数组。

    // ...
    'filters' => [
        'array' => true
    ]
    // ...

boolean => true

将值转换为布尔值

    // ...
    'filters' => [
        'boolean' => true
    ]
    // ...

float => true

将值转换为浮点数

    // ...
    'filters' => [
        'float' => true
    ]
    // ...

integer

将值转换为整数

    // ...
    'filters' => [
        'integer' => true
    ]
    // ...

json_encode

使用 json_encode 函数编码对象

    // ...
    'filters' => [
        'json_encode' => true
    ]
    // ...

lowercase

将值转换为小写

    // ...
    'filters' => [
        'lowercase' => true
    ]
    // ...

object

将值转换为对象

    // ...
    'filters' => [
        'object' => true
    ]
    // ...

round => true | decimal

四舍五入数值。可选地设置总小数位数。

    // ...
    'filters' => [
        // 'round' => true,
        'round' => 2
    ]
    // ...

string

将值转换为字符串

    // ...
    'filters' => [
        'string' => true
    ]
    // ...

ucwords

使用函数 ucwords 转换值

    // ...
    'filters' => [
        'ucwords' => true
    ]
    // ...

uppercase

将值转换为大写

    // ...
    'filters' => [
        'uppercase' => true
    ]
    // ...

自定义验证规则

请按照以下步骤创建新的验证规则

创建规则处理程序

创建一个新的类来处理验证。

<?php

namespace MyModule\Module;

class Validator
{
    public static function custom(
        mixed  $value,
        mixed  $options,
        object $object,
        string $fname,
        array  $rules
    ) {
        // most of the time, the null value is for `required` rule.
        // leave it for it.
        if (is_null($value)) {
            return null;
        }

        if (/* check the $value */) {
            return null; // it's valid
        }

        // its not valid
        return ['100.0'];
        // return ['100.0', ['a'=>'b']];
        // return ['100.0', ['a'=>'b'], 'Error message'];
    }
}

如果值有效,则该方法应返回 null。如果返回数组,则至少有一个数组成员,最多三个成员。每个成员如下所示

  1. 索引 0。错误代码。
  2. 索引 1。翻译参数,传递给翻译函数
  3. 索引 2。自定义翻译键

如果索引 2 不存在,则使用配置中的默认翻译。

该方法将以下参数调用

mixed $value

用户提交的值。如果值未提交,则将为 null。大多数情况下,您不想处理 null 值。将其留给 required 规则。

mixed $options

从配置中获取的规则数组值。下面是一个示例

    // ...
    'rules' => [
        'custom' => 'awesome'
    ]
    // ...

此参数的值将是 awesome

object $object

正在验证的完整对象属性。

string $fname

正在从 $object 对象中验证的字段名称。

array $rules

将要应用于字段的全部规则。

注入验证配置

在你的模块中创建一个新的 ConfigProvider,并在文件中填充 __invoke 方法,该方法返回验证配置

<?php

// ...
    return [
        'validator' => [
            // error translation key
            'errors' => [
                '/code/' => '/translation key',
                '100.0' => 'the value is not accepted'
            ],
            'validators' => [
                'custom' => 'MyModule\\Module\\Validator::custom'
            ]
        ]
    ];
// ...

确保更新你的 composer.json 文件,以便 hyperf 识别配置文件

    "extra": {
        "hyperf": {
            "config": "Vendor\\Module\\ConfigProvider"
        }
    }

创建错误翻译

本模块使用hyperf/translation进行翻译。在文件夹storage/languages/vendor/validator/{locale}/{rule-name}.php中添加新的翻译。

<?php

return [
    'the value is not accepted' => 'The value is not accepted.'
];

自定义验证过滤器

关于验证规则,过滤器也可以自定义。请按照以下步骤创建新的过滤器

创建过滤器处理器

创建一个处理过滤器的类。

<?php

namespace MyModule\Module;

class Filter
{
    public static function custom(
        mixed  $value,
        mixed  $options,
        object $object,
        string $fname,
        array  $rules
    ) {
        // most of the time, it's not processed if it's null.
        if (is_null($value)) {
            return null;
        }

        // modify the $value;

        return $value;
    }
}

该方法将被调用,与自定义规则验证处理器调用的方式完全相同。

注入验证配置

在你的模块中创建一个新的 ConfigProvider,并在文件中填充 __invoke 方法,该方法返回验证配置

<?php
// ...
    return [
        'validator' => [
            'filters' => [
                'custom' => 'MyModule\\Module\\Filter::custom'
            ]
        ]
    ];
// ...

确保更新你的 composer.json 文件,以便 hyperf 识别配置文件

    "extra": {
        "hyperf": {
            "config": "Vendor\\Module\\ConfigProvider"
        }
    }

自定义错误格式化器

默认情况下,由类返回的错误格式如下

stdClass Object
(
    [field] => name
    [code] => 11.0
    [text] => This field is required
    [options] => Array
        (
            [label] => Name
            [rules] => Array
                (
                    [required] => 1
                )

            [name] => name
        )

)

如果您需要,可以修改错误对象的结构。创建一个实现接口Iqomp\Validator\ErrorFormatterInterface的类,内容如下

<?php

namespace MyModule\Formatter;

use Iqomp\Validator\ErrorFormatterInterface;

class MyErrorFormatter implements ErrorFormatterInterface
{
    public static function format(object $err, string $fld, array $errs, object $obj)
    {
        return [$err->text];
    }
}

之后,可以通过以下方式之一注册处理器

应用配置

这种方式将始终为您所有的请求和验证使用您的处理器。

创建名为config/autoload/validator.php的配置文件,并填写以下内容

<?php

return [
    'formatter' => 'MyModule\\Formatter\\MyErrorFormatter'
];

即时配置

您可以通过调用Validator::setErrorFormatter来即时设置格式化器。这将仅对当前请求有效。您需要为每个请求调用它。

<?php

use MyModule\Formatter\MyErrorFormatter;
use Iqomp\Validator\Validator;

Validator::setErrorFormatter(MyErrorFormatter::class);

表单

Iqomp\Validator\Form是一个分离规则配置和验证对象的类。该类使控制器中的对象验证变得更加简单,因为所有对象验证规则都存储在一个配置文件中。如果未提供要验证的对象,则将从请求体中获取。

use Iqomp\Validator\Form;

$f_params = [
    'param1' => 'id',
    'param2' => 1
];

$form   = new Form('form-name', $f_params);
$result = $form->validate();

if (!$result) {
    $errors = $form->getErrors();
}

参数$f_params用于替换以$.开头的任何规则字符串。请参阅以下参数使用示例。

表单配置

与之前一样,您需要为表单名称创建规则列表,以便能够以这种方式使用。

在您的应用主目录中创建名为config/autoload/form.php的新文件,内容如下

<?php

return [
    'forms' => [
        '/form-name/' => [
            '/field/' => [
                'rules' => [
                    // list of rules
                    'some-rule' => [
                        '$.param1' => '$.param2'
                    ]
                ],
                'filters' => [
                    // list of filters
                ]
            ]
        ]
    ]
];

方法

Iqomp\Validator\Form具有以下方法

__construct(string $name): Form

创建一个新的表单对象,表单为$name

addError(string $field, string $code, string $text): void

$field添加自定义错误,错误代码为$code,错误消息为$text。此操作不会将错误消息从错误代码翻译过来,您需要在您的操作中完成它。

getError(string $field): ?object

通过$field名称获取单个错误对象。结构如下

stdClass Object
(
    [field] => name
    [code] => 11.0
    [text] => This field is required
    [options] => Array
        (
            [label] => Name
            [rules] => Array
                (
                    [required] => 1
                )

            [name] => name
        )

)

getErrors(): array

获取所有存在的错误,以数组形式返回,字段->(对象)错误对。结构如下

Array
(
    [name] => stdClass Object
        (
            [field] => name
            [code] => 11.0
            [text] => This field is required
            [options] => Array
                (
                    [rules] => Array
                        (
                            [required] => 1
                        )

                    [name] => name
                )

        )

)

getName(): string

获取当前表单名称。

getResult(): ?object

获取验证的最终结果。

hasError(): bool

检查验证后此表单是否存在错误。

validate(object $object = null): ?object

根据配置对$object进行验证。如果$object为null,则值将来自请求体。

错误代码

以下是目前定义的所有错误代码列表