bus-factor / ares
轻量级的独立验证库
Requires
- php: >=7.3
- ext-json: *
- bus-factor/ddd: ^5.0
Requires (Dev)
- phpunit/phpunit: >=5.7
This package is auto-updated.
Last update: 2024-09-07 14:22:45 UTC
README
__ _ _ __ ___ ___
/ _` | '__/ _ \/ __|
| (_| | | | __/\__ \
\__,_|_| \___||___/
Ares 是一个轻量级的独立验证库。
目录
安装
通过 composer 安装库
composer require bus-factor/ares
基本用法
<?php use Ares\Ares; // atomic types $ares = new Ares(['type' => 'string']); $valid = $ares->validate('John Doe'); $errors = $ares->getValidationErrors(); // complex/nested types $ares = new Ares([ 'type' => 'map', 'schema' => [ 'firstName' => ['type' => 'string', 'required' => true], 'lastName' => ['type' => 'string', 'required' => true], ], ]); $valid = $ares->validate(['firstName' => 'John', 'lastName' => 'Doe']); $errors = $ares->getValidationErrors();
验证错误
validate() 方法返回 true 如果提供的数据有效,否则返回 false。
getValidationErrors() 方法返回一个 Ares\Validation\Error\ErrorCollection 对象,该对象包含在最后的数据验证过程中收集的 Ares\Validation\Error\Error 实例列表。每次调用 validate() 时,验证错误列表都会重置。
每个 Ares\Validation\Error\Error 对象实现 JsonSerializable 接口并包含有关错误的详细信息。
Ares\Validation\Error\ErrorCollection 对象是可迭代的,但也提供了两个便利方法
::toArrayJsonApiStyle()- 返回一个数组,该数组反映了 json:api 规范::toArrayNested- 返回一个嵌套数组,其中错误信息与其嵌套结构匹配输入数据的结构
验证选项
验证选项可以在验证时传递
$schema = []; $options = []; $ares = new Ares($schema, $options);
默认验证选项是
Validator::OPTIONS_DEFAULTS = [ 'allBlankable' => false, 'allNullable' => false, 'allRequired' => true, 'allUnknownAllowed' => false, ]
allBlankable
此选项仅适用于 string 类型。如果设置为 true,则空白值被视为有效。如果设置为 false,则空白值被视为无效。
$schema = [ 'type' => 'map', 'schema' => [ 'name' => ['type' => 'string'], ], ]; $ares = new Ares($schema); $ares->validate(['name' => ''], ['allBlankable' => true]); // -> true $ares->validate(['name' => ''], ['allBlankable' => false]); // -> false
可以使用 blankable 规则按字段覆盖此选项
$schema = [ 'type' => 'map', 'schema' => [ 'name' => ['type' => 'string'], 'email' => ['type' => 'string', 'blankable' => true], ], ]; $ares->validate(['name' => 'John Doe', 'email' => ''], ['allBlankable' => false]); // -> true
allNullable
如果设置为 true,则 null 被视为有效值。如果设置为 false,则 null 不被视为有效值。
$schema = [ 'type' => 'map', 'schema' => [ 'name' => ['type' => 'string'], ], ]; $ares->validate(['name' => null], ['allNullable' => true]); // -> true $ares->validate(['name' => null], ['allNullable' => false]); // -> false
可以使用 nullable 规则按字段覆盖此选项
$schema = [ 'type' => 'map', 'schema' => [ 'name' => ['type' => 'string'], 'email' => ['type' => 'string', 'nullable' => true], ], ]; $ares->validate(['name' => 'John Doe', 'email' => null], ['allNullable' => false]); // -> true
allRequired
如果设置为 true(默认)字段在模式中定义但不在输入中,则被视为无效。如果设置为 false,则字段在模式中定义但不在输入中,则被视为有效。
$schema = [ 'type' => 'map', 'schema' => [ 'name' => ['type' => 'string'], ], ]; $ares = new Ares($schema); $ares->validate([], ['allRequired' => true]); // -> false $ares->validate([], ['allRequired' => false]); // -> true
可以使用 required 规则按字段覆盖此选项
$schema = [ 'type' => 'map', 'schema' => [ 'name' => ['type' => 'string'], 'email' => ['type' => 'string', 'required' => false], ], ]; $ares = new Ares($schema); $ares->validate(['name' => 'John Doe'], ['allRequired' => true]); // -> true
allUnknownAllowed
此选项仅适用于 map 类型。如果设置为 true,则在输入数据中出现但未在模式中定义的字段被视为无效。如果设置为 false,则这些字段被视为有效。
$schema = [ 'type' => 'map', 'schema' => [ 'name' => ['type' => 'string'], ], ]; $ares = new Ares($schema); $ares->validate(['name' => 'John Doe', 'initials' => 'JD'], ['allUnknownAllowed' => false]); // -> false $ares->validate(['name' => 'John Doe', 'initials' => 'JD'], ['allUnknownAllowed' => true]); // -> true
验证规则
allowed
allowed 验证规则检查值是否在给定的允许值集合(枚举)中。
示例
$ares = new Ares(['type' => 'string', 'allowed' => ['small', 'large']]); $ares->validate('medium'); // -> false $ares->validate('small'); // -> true
《允许》验证规则与《禁止》验证规则相反。
可空白
《可空白》规则仅适用于《字符串》类型的数据。如果设置为《true》,空白字符串被视为有效。如果设置为《false》,空白字符串被视为无效(默认)。
示例
$ares = new Ares(['type' => 'string', 'blankable' => false]); $ares->validate(''); // -> false $ares->validate(' '); // -> false $ares->validate('John Doe'); // -> true $ares = new Ares(['type' => 'string', 'blankable' => true]); $ares->validate(' '); // -> true
《可空白》验证规则可以与《全部可空白》验证选项一起使用。
日期时间
《日期时间》验证规则仅适用于《字符串》类型的数据。如果设置为《true》,任何可解析的日期时间字符串被视为有效。如果设置为《false》,将不会进行日期时间的验证。如果设置特定的日期时间格式字符串,则还会检查给定的值是否与该格式匹配。有关格式字符串的详细信息,请参阅DateTime::createFromFormat()。
示例
$ares = new Ares(['type' => 'string', 'datetime' => true]); $ares->validate('foo'); // -> false $ares->validate('2018-03-23'); // -> true $ares = new Ares(['type' => 'string', 'datetime' => 'd.m.Y H:i']); $ares->validate('2018-03-23'); // -> false $ares->validate('23.03.2019 00:20'); // -> true
目录
《目录》验证规则检查给定的字符串值是否包含指向现有目录的路径。如果设置为《true》,只有指向现有目录的路径被视为有效。如果设置为《false》,所有输入都被视为有效(不进行验证)。
示例
$ares = new Ares(['type' => 'string', 'directory' => true]); $ares->validate(''); // -> false $ares->validate(__FILE__); // -> false $ares->validate(__DIR__); // -> true
电子邮件
《电子邮件》验证规则检查值是否为有效的电子邮件地址。如果设置为《true》,只有有效的电子邮件地址被视为有效。如果设置为《false》,所有输入都被视为有效(不进行验证)。
示例
$ares = new Ares(['type' => 'string', 'email' => true]); $ares->validate('John Doe'); // -> false $ares->validate('john.doe@example.com'); // -> true
文件
《文件》验证规则检查给定的字符串值是否包含指向现有文件的路径。如果设置为《true》,只有指向现有文件的路径被视为有效。如果设置为《false》,所有输入都被视为有效(不进行验证)。
示例
$ares = new Ares(['type' => 'string', 'file' => true]); $ares->validate(''); // -> false $ares->validate(__DIR__); // -> false $ares->validate(__FILE__); // -> true
禁止
《禁止》验证规则检查值是否在给定的禁止值集合(枚举)中。
示例
$ares = new Ares(['type' => 'string', 'forbidden' => ['small', 'medium']]); $ares->validate('medium'); // -> false $ares->validate('large'); // -> true
《禁止》验证规则与《允许》验证规则相反。
长度
《长度》验证规则适用于《字符串》和《列表》类型的数据。《长度》验证规则检查字符串或列表是否具有指定的确切长度。
示例
$ares = new Ares(['type' => 'string', 'length' => 3]); $ares->validate('foobar'); // -> false $ares->validate('foo'); // -> true $ares = new Ares([ 'type' => 'list', 'length' => 3, 'schema' => [ 'type' => 'integer' ], ]) $ares->validate([1, 2]); // -> false $ares->validate([1, 2, 3]); // -> true
最大值
《最大值》验证规则仅适用于《浮点数》和《整数》类型的数据。《最大值》验证规则检查值是否等于或小于指定的最大值。
示例
$ares = new Ares(['type' => 'integer', 'max' => 5]); $ares->validate(6); // -> false $ares->validate(2); // -> true
注意当与不支持的数据类型一起使用时,此验证规则将抛出《Ares\Exception\InapplicableValidationRuleException》异常。
最大长度
《最大长度》验证规则适用于《字符串》和《列表》类型的数据。《最大长度》验证规则检查字符串或列表是否不超出指定的最大长度。
示例
$ares = new Ares(['type' => 'string', 'maxlength' => 5]); $ares->validate('foobar'); // -> false $ares->validate('foo'); // -> true $ares = new Ares([ 'type' => 'list', 'maxlength' => 3, 'schema' => [ 'type' => 'integer' ], ]) $ares->validate([1, 2, 3, 4]); // -> false $ares->validate([1, 2, 3]); // -> true
最小值
《最小值》验证规则仅适用于《浮点数》和《整数》类型的数据。《最小值》验证规则检查值是否等于或大于指定的最小值。
示例
$ares = new Ares(['type' => 'integer', 'min' => 5]); $ares->validate(4); // -> false $ares->validate(8); // -> true
注意当与不支持的数据类型一起使用时,此验证规则将抛出《Ares\Exception\InapplicableValidationRuleException》异常。
最小长度
《最小长度》验证规则适用于《字符串》和《列表》类型的数据。《最小长度》验证规则检查字符串或列表是否不短于指定的最小长度。
示例
$ares = new Ares(['type' => 'string', 'minlength' => 5]); $ares->validate('foo'); // -> false $ares->validate('foobar'); // -> true $ares = new Ares([ 'type' => 'list', 'minlength' => 3, 'schema' => [ 'type' => 'integer' ], ]) $ares->validate([1, 2]); // -> false $ares->validate([1, 2, 3]); // -> true
可空
如果设置为《true》,《null》被视为有效值。如果设置为《false》,《null》被视为无效值(默认)。
示例
$ares = new Ares(['type' => 'string', 'nullable' => false]); $ares->validate(null); // -> false $ares->validate('John Doe'); // -> true $ares = new Ares(['type' => 'string', 'nullable' => true]); $ares->validate(null); // -> true
《可空》验证规则可以与《全部可空》验证选项一起使用。
正则表达式
正则表达式验证规则仅适用于 string 类型的值。正则表达式验证规则检查一个字符串是否与正则表达式匹配。
示例
$ares = new Ares([ 'type' => 'map', 'schema' => [ 'key' => [ 'type' => 'string', 'regex' => '/^[A-Z]{3}$/', ], ], ]); $ares->validate(['key' => 'foobar']); // -> false $ares->validate(['key' => 'FOO']); // -> true
必填
使用 required 规则来强制值的存在。如果设置为 true,则空字段被视为无效。如果设置为 false(默认值),则空字段被视为有效。
示例
$ares = new Ares([ 'type' => 'map', 'schema' => [ 'name' => ['type' => 'string', 'required' => true], ], ]); $ares->validate([]); // -> false $ares->validate(['name' => 'John Doe']); // -> true
required 验证规则可以与 allRequired 验证选项结合使用。
模式
当使用类型 list、map 或 tuple 时,schema 规则是必需的。
模式(列表)
验证器期望模式定义列表项的验证规则。
示例
$ares = new Ares([ 'type' => 'list', 'schema' => [ 'type' => 'integer', ], ]); $ares->validate(['foo', 'bar']); // -> false $ares->validate([1, 2, 3]); // -> true
模式(映射)
验证器期望模式为关联数组输入定义每个字段的验证规则。
示例
$ares = new Ares([ 'type' => 'map', 'schema' => [ 'email' => ['type' => 'string', 'required' => true], 'password' => ['type' => 'string', 'required' => true], ], ]); $ares->validate(['email' => 'john.doe@example.com']); // -> false $ares->validate(['email' => 'john.doe@example.com', 'password' => 'j4n3:)']); // -> true
模式(元组)
验证器期望模式为输入数组元素定义验证规则。在验证过程中,输入数组元素应从 0 开始的连续索引(0, 1, 2, ...)。
示例
$ares = new Ares([ 'type' => 'tuple', 'schema' => [ ['type' => 'string', 'email' => true], ['type' => 'integer'], ], ]); $ares->validate(['john.doe@example.com']); // -> false $ares->validate([1 => 'john.doe@example.com', 2 => 23]); // -> false $ares->validate(['john.doe@example.com', 23]); // -> true
在内部,元组的所有 schema 元素都是必需的,并且不能通过模式声明为可选。
类型
type 规则是必需的,并定义了预期/允许的值类型。支持的类型有:
布尔型浮点型整型numeric(float或integer)字符串映射列表元组
示例
$ares = new Ares(['type' => 'float']); $ares->validate(5); // -> false $ares->validate('John Doe'); // -> false
请参阅自定义类型部分,了解如何定义和重用您自己的类型。
unknownAllowed
unknownAllowed 验证规则检查一个 map 是否包含在模式中未定义的字段。如果设置为 true,则模式中未定义的字段被视为有效。如果设置为 false,则模式中未定义的字段被视为无效。
示例
$ares = new Ares([ 'type' => 'map', 'schema' => [ 'name' => ['type' => 'string'], ], 'unknownAllowed' => false, ]); $ares->validate(['name' => 'John Doe', 'email' => 'john.doe@example.com']); // -> false $ares->validate(['name' => 'John Doe']); // -> true
url
url 验证规则检查值是否是有效的 URL。
示例
$ares = new Ares(['type' => 'string', 'url' => true]); $ares->validate('example'); // -> false $ares->validate('https://example.com'); // -> true
uuid
uuid 验证规则检查值是否是有效的 UUID。
示例
$ares = new Ares(['type' => 'string', 'uuid' => true]); $ares->validate('example'); // -> false $ares->validate('609de7b6-0ef5-11ea-8d71-362b9e155667'); // -> true
自定义类型
基本上,自定义类型是用户定义的模式,它存储在并从注册表中检索。以下是一个示例,说明它是如何工作的
use Ares\Ares; use Ares\Schema\TypeRegistry; TypeRegistry::register('GermanDateString', [ 'type' => 'string', ['datetime' => 'd.m.Y', 'message' => 'Invalid date format, try something like "24.02.2019"'], ]); TypeRegistry::register('ListOfHobbies', [ 'type' => 'list', 'schema' => [ 'type' => 'string', 'allowed' => ['Reading', 'Biking'], ], ]); TypeRegistry::register('Student', [ 'type' => 'map', 'schema' => [ 'birthDate' => ['type' => 'GermanDateString'], 'hobbies' => ['type' => 'ListOfHobbies', 'minlength' => 1], ], ]); $schema = ['type' => 'Student']; $ares = new Ares($schema); $ares->validate(['birthDate' => '1998-06-14', 'hobbies' => []]); // false $ares->validate(['birthDate' => '14.06.1998', 'hobbies' => ['Reading']]); // true
使用 TypeRegistry::unregister() 注销先前注册的类型。使用 TypeRegistry::unregisterAll() 一次性注销所有先前注册的类型。还可以定义递归类型。
自定义验证错误消息
更改单个规则的验证错误消息
以下示例展示了如何自定义验证错误消息
// validation rule without custom message (default) $ares = new Ares([ 'type' => 'integer', ]); // validation rule with custom message $ares = new Ares([ ['type' => 'integer', 'message' => 'Pleaser provide an integer value'] ]);
只需将您的规则(键值)包装在一个数组中,并添加一个 'message' 键。
验证错误消息本地化
所有内置验证规则都使用 Ares\Error\ErrorMessageRendererInterface 来渲染消息。如果没有指定,则创建一个 Ares\Error\ErrorMessageRenderer 实例并将其传递给验证过程。如果需要,可以将自定义错误消息渲染器传递给验证器
use Ares\Ares; use Ares\Validation\Error\ErrorMessageRendererInterface; class MyErrorMessageRenderer implements ErrorMessageRendererInterface { // ... } // ... $ares = new Ares($schema); $ares->getValidator()->setErrorMessageRenderer(new MyErrorMessageRenderer()); $valid = $ares->validate($data);
自定义验证规则
以下简单示例展示了如何实现和集成自定义验证规则
use Ares\Ares; use Ares\Schema\Type; use Ares\Validation\Context; use Ares\Validation\RuleRegistry; use Ares\Validation\Rule\AbstractRule; class ZipCodeRule extends AbstractRule { public const ID = 'zipcode'; public const ERROR_MESSAGE = 'Invalid ZIP code'; /** * Returns all supported value types. * * @return array */ public function getSupportedTypes(): array { return [ Type::STRING, ]; } /** * Perform the value validation. * * @param mixed $args Validation rule arguments. * @param mixed $data Data being validated. * @param Context $context Validation context. * @return bool */ public function performValidation($args, $data, Context $context): bool { // implement validation ... // add error if the validation fails $context->addError(self::ID, self::ERROR_MESSAGE); // TRUE - skip all following validation rules for the current field // FALSE - run all following validation rules for the current field return false; } } RuleRegistry::register(ZipCodeRule::ID, new ZipCodeRule()); $schema = [ 'type' => 'string', 'zipcode' => true, ]; $ares = new Ares($schema);
清理
以下示例展示了如何清理数据
$schema = [ 'type' => 'map', 'schema' => [ 'name' => ['type' => 'string'], 'age' => ['type' => 'integer'], 'active' => ['type' => 'boolean'], ], ]; $ares = new Ares($schema); $data = [ 'name' => ' John Doe ', 'age' => '23', 'active' => '1', 'hobby' => 'Reading', ]; $sanitizedData = $ares->sanitize($data); // Result: // [ // 'name' => 'John Doe', // 'age' => 23, // 'active' => true, // ]
如示例所示,默认情况下清理会进行以下调整:
- 修剪字符串
- 将数字字符串转换为整数或字符串值
- 将非空数字字符串转换为布尔值
- 从输入数据中删除未知字段
清理选项
trimStrings
如果设置为 true(默认值),则从字符串中删除周围的空白。如果设置为 false,则保留周围的空白。
purgeUnknown
如果设置为 true(默认值),则从输入数据中删除未知字段(在模式中未定义的字段/索引)。如果设置为 false,则保留未知字段。