jsl / ensure
README
安装
使用Composer
composer require jsl/ensure
基本示例
use Jsl\Ensure\Ensure; $values = [ 'name' => 'Mr Magoo', 'age' => 77, ]; $rules = [ 'name' => ['required', 'type' => 'string', 'minSize' => 20], 'age' => ['required', 'type' => 'integer', 'minSize' => 80], ]; // Create a new validation instance $ensure = new Ensure($rules, $values); // Validate the values against the rules $result = $ensure->validate(); // Check if the validation was successful $result->isValid(); // Returns true or false // If validation failed, get array of validation errors print_r($result->getErrors()); // Returns: // // Array // ( // [name] => Array // ( // [0] => Size of name must be at least 20 // ) // [age] => Array // ( // [0] => Size of age must be at least 80 // ) // )
管理规则
$rules = [ 'name' => ['required', 'type' => 'string', 'minSize' => 20], 'age' => ['required', 'type' => 'integer', 'minSize' => 80], ]; // Pass them through the constructor $ensure = new Ensure($rules, $values); // Add/replace a rule on an existing instance // setFieldRule(string $field, string $rule, ...$args) $ensure->setFieldRule('name', 'minSize', 10); // Add/replace multiple rules on an existing instance // setFieldRules(string $field, array $rules) $ensure->setFieldRules('age', ['type' => 'string', 'minSize' => 70]); // Remove a field rule // removeRule(string $field, string $rule) $ensure->removeFieldRule('age', 'type');
管理值
$values = [ 'name' => 'Mr Magoo', 'age' => 77, ]; // Pass them through the constructor // You can pass $_POST or $_GET directly as well $ensure = new Ensure($rules, $values); // Add/replace a value on an existing instance // seFieldValue(string $field, mixed $value) $ensure->setFieldValue('name', 'Mrs Magoo'); // Replace all values // replaceValues(array $values) $ensure->replaceValues([ 'name' => 'Mrs Magoo', 'age' => 70 ]);
获取结果 & 错误
// Validate the values against the rules and get the result $result = $ensure->validate(); // Check if the validation was successful $result->isValid(); // Returns true or false // Getting potential errors (returns all failed rules for the fields) // This will return an array [fieldname => [error1, error2, ...]] $errors = $result->getErrors(); // To only get the first failed rule, pass "true" to the method // This will return an array [fieldname => error1, fieldname2 => error1, ...] $errors = $result->getErrors(true);
管理错误模板
由于您可能不喜欢验证器返回的默认错误模板/消息,因此有几种方法可以自定义它们
// Set the default error template for a specific rule // This will replace the error template for this rule for all fields $ensure->setRuleTemplate('rule', '{field} has failed {a:0}'); // Set the default error template for a specific rule for a specific field // This will only replace the error template for this rule for the specific field $ensure->setFieldRuleTemplate('field', 'rule', '{field} has failed {a:0}'); // Set a single error template for a specific field, regardless of which rule failed // Note: This will only replace rule templates, not field rule templates set with setFieldRuleTemplate() $ensure->setFieldTemplate('field', 'rule', '{field} has failed {a:0}'); // To remove a previously added error template, pass in null as the message // This works on all the above methods $ensure->setRuleTemplate('rule', null);
注意:这些方法也适用于 Result
实例,因此您不需要在验证之前在 Ensure 实例上定义它们。
错误模板解释
错误模板是当规则/字段失败时返回的错误消息。它们可以包含将在错误渲染时解决的占位符。
$template = '{field} must be {a:0}'; // {field} will be replaced with the field name // {a:0} will be replaced with the value from the first argument // {a:1} will be replaced with the value from the second argument // ...you can have as many `{a:x}` as there are arguments for the rule
注意:仅当使用 setFieldTemplate()
添加模板时,才会替换 {field}
占位符,因为这是该字段的通用消息,而不是特定规则的。
设置花哨的字段名
当向用户显示错误(特别是在网页上)时,您不希望使用输入名称。为了解决这个问题,您可以设置“花哨”的字段名,这些字段名将在渲染错误模板时使用。
// Set multiple fancy names in one go $ensure->setFancyNames([ 'name' => 'The name', 'age' => 'The age', ]);
设置花哨名称的另一种方法是使用规则 as
。
// Either through the rules array $rules = [ 'name' => [ 'required', 'as' => 'A fancy field name', ], ]; // Or adding it as any other rule $ensure->setFieldRule('fieldname', 'as', 'Fancy field name');
管理验证器
验证器是验证库的核心和灵魂。没有它们,其余部分将相当无意义。
如果您缺少/需要默认集合中未包含的某些验证器,您可以轻松地添加自己的。您可以添加任意多个。
自定义验证器
要添加验证器,您可以使用
// addValidator(string $name, mixed $callback, ?string $template = null)
$ensure->addValidator($name, $callback, $optionalTemplate);
$name
将是验证器的规则名称。$callback
是验证器。它可以是许多类型之一的回调。有关更多信息,请参阅下文。$template
是验证器失败时返回的错误模板。它是可选的,但可能很有用。
您的验证器应在通过时返回
true
,在失败时返回false
。
您可以添加任意多的自定义验证器,并且可以以多种不同的方式创建它们。
验证器可以是可调用的,完全限定的类名,类实例,包含类名/实例和方法的数组。
无论您使用哪种类型的回调,您都可以在添加验证器时将错误模板作为第三个参数传递。但是,为了可读性,我省略了它们。
闭包
添加简单验证器最简单的方法
$ensure->addValidator('between', function ($value, $min, $max): bool { return $value >= $min && $value <= $max; });
完全限定的类名
这要求类使用魔法方法 __invoke()
class BetweenValidator { public function __invoke($value, $min, $max): bool { return $value >= $min && $value <= $max;; } } $ensure->addValidator('between', BetweenValidator::class); // You can also pass it as an instance $ensure->addValidator('between', new BetweenValidator);
包含完全限定的类名 & 方法的数组
class MyValidators { public function myBetweenMethod($value, $min, $max): bool { return $value >= $min && $value <= $max; } } $ensure->addValidator('between', [MyValidators::class, 'myBetweenMethod']); // You can also use an instance $ensure->addValidator('between', [new MyValidators, 'myBetweenMethod']);
命名函数
function myBetweenFunc($value, $min, $max): bool { return $value >= $min && $value <= $max; } $ensure->addValidator('between', 'myBetweenFunc');
在验证器中使用其他字段值
如果您想在验证器中访问其他字段值,则选项有限。创建一个实现 Jsl\Ensure\Contracts\ValidatorInterface
的类
最简单的方法是扩展 Jsl\Ensure\Abstracts\Validator
,它实现了该接口并带有所有必要的方法
想象一下规则
$rule = [ 'theValueField' => [ 'sameAsField' => ['anotherValueField'] ], ];
实现可能如下所示
class AreFieldsSameValidator extends \Jsl\Ensure\Abstracts\Validator { /** * Check if two values are the same * * @param mixed $value The value * @param string $field The name of the other field * * @return bool */ public function __invoke($value, $field): bool { return $value === $this->getValue($field); } /** * For classes implementing the ValidatorInstance, * we should add the error template like this * * @return string */ public function getTemplate(): string { return '{field} must be the same as {a:0}'; } } $ensure->addValidator('sameAsField', AreFieldsSameValidator::class);
类解析器
默认情况下,Ensure 将以最简单的方式创建任何完全限定的类的实例
return new $className;
这完全正常,除非您想使用一些 IoC/依赖注入容器来实例化您的验证器类并注入一些依赖项。
幸运的是,您可以通过闭包的形式添加自己的类解析器。
它可能看起来像这样
$ensure->setClassResolver(function (string $className) use ($yourContainer) { return $yourContainer->has($className) ? $yourContainer->get($className) : new $className; });
现在所有验证器类都将使用该闭包进行解析(包括默认验证器)
工厂
到目前为止,我们只讨论了如何向特定的Ensure实例添加错误模板和验证器
通过使用工厂,您可以在更高的层面完成所有这些操作,确保所有新实例继承这些设置
use Jsl\Ensure\EnsureFactory; $factory = new EnsureFactory; $factory->setFieldTemplate(...) ->setFieldRuleTemplate(...) ->setRuleTemplate(...) ->setClassResolver(...) ->addValidator(...); // To get an Ensure instance that inherits those settings $ensure = $factory->create($rules, $data);
现有规则
这些是默认规则
如果您想替换其中任何一个的实现,只需添加一个同名验证器即可
如果规则只有一个参数,您可以直接传递
'rule' => 'arg'
如果规则需要多个参数,可以将它们作为一个数组传递
'rule' => ['arg1', 'arg2']
required - 不能替换 将字段设置为必填。如果不要求且缺失,则将其忽略。如果设置为必填且缺失,则验证失败。
参数: N/A
nullable - 不能替换
将字段设置为可空。如果值为可空且为 null
,则跳过任何进一步的规则。如果不可空且值为 null
,则验证失败。
参数: N/A
as - 不能替换
为要在错误模板中使用的字段设置一个花哨的名称。
参数: (string $fancyName)
示例: 'as' => 'A fancy name'
alphanum
检查字符串是否只包含字母数字字符
参数: N/A
alpha
检查字符串是否只包含字母字符
参数: N/A
email
检查字符串是否为有效的电子邮件地址
参数: N/A
hex
检查字符串是否为十六进制十进制值
参数: N/A
ip
检查字符串是否为有效的IP地址
参数: N/A
mac
检查字符串是否为有效的MAC地址
参数: N/A
url
检查字符串是否为有效的URL
参数: N/A
size
检查值是否为特定的大小。
- 如果是数组,则使用
count()
- 如果是字符串,则使用
strlen()
- 如果是整数或十进制数,则比较值
参数: (int $size)
示例: 'size' => 10
minSize
检查值的尺寸是否至少为 x
- 如果是数组,则使用
count()
- 如果是字符串,则使用
strlen()
- 如果是整数或十进制数,则比较值
参数: (int $size)
示例: 'minSize' => 5
maxSize
检查值的尺寸是否最多为 x。
- 如果是数组,则使用
count()
- 如果是字符串,则使用
strlen()
- 如果是整数或十进制数,则比较值
参数: (int $size)
示例: 'maxSize' => 30
in
检查值是否存在于值列表中。类似于 in_array()
参数: (array $haystack)
示例: 'in' => [1,2,3,4]
notIn
检查值是否不在值列表中。类似于 in_array() === false
参数: (array $haystack)
示例: 'notIn' => [1,2,3,4]
same
检查值是否与另一个字段的值相同
参数: (string $fieldname)
示例: 'same' => 'nameOfAnotherField'
different
检查值是否与另一个字段的值不同
参数: (string $fieldname)
示例: 'different' => 'nameOfAnotherField'
type
检查值是否为特定类型
参数: (string $type)
示例: 'type' => 'string'
可能的值: string
, numeric
, integer
, decimal
, array
, boolean
规则集
如果您需要在多个地方使用相同的规则列表,手动在所有这些地方添加它们可能不太有效。
而不是传递包含规则的数组,您可以将它们作为规则集添加到您的主 EnsureFactory
-实例
$factory->addRuleset('myRuleset', [ 'name' => [ 'required', 'minSize' => 5, ], 'age' => [ 'required', 'minSize' => 18, ], ]);
要使用规则集,在创建新的 Ensure
-实例时,使用工厂传递规则集名称而不是规则列表
$ensure = $factory->create('myRuleset', $_POST);