guyliangilsing / php-validation
一个简单的验证库,允许您为数据编写自定义验证器。
Requires
- php: >=8.1
Requires (Dev)
- dg/bypass-finals: ^1.4
- nunomaduro/phpinsights: ^2.2
- phpunit/phpunit: 9.5
README
一个简单的验证库,允许您为数据编写自定义验证器。
目录
- PHPValidation
- 目录
- 特性
- 安装
- 用法
- 可用的字段验证器
- required
- notEmpty
- isArray
- hasKeys
- hasValues
- confirmValues
- in
- notIn
- minLength
- maxLength
- minCount
- maxCount
- phoneNumber
- isAlphabetic
- isNumeric
- isAlphaNumeric
- isInt
- isFloat
- isString
- isObject
- objectOfType
- equals
- contains
- greaterThan
- greaterEqual
- lowerThan
- lowerEqual
- between
- isDate
- dateHasFormat
- dateEquals
- dateLowerThan
- dateLowerEqual
- dateGreaterThan
- dateGreaterEqual
- dateBetween
特性
PHPValidation 包含以下特性
- 通过简单整洁的接口进行数组验证
- 支持自定义字段验证器
- 内置基本用例的字段验证器
required字段验证器notEmpty字段验证器,适用于字符串和数组isArray字段验证器hasKeys字段验证器,适用于数组hasValues字段验证器,适用于数组confirmValues字段验证器,适用于数组in字段验证器,适用于字符串、浮点数、整数、布尔值和包含上述类型的数组notIn字段验证器,适用于字符串、浮点数、整数和布尔值minLength字段验证器,适用于字符串maxLength字段验证器,适用于字符串minCount字段验证器,适用于数组maxCount字段验证器,适用于数组email字段验证器,适用于字符串phoneNumber字段验证器,适用于字符串isAlphabetic字段验证器,适用于字符串isNumeric字段验证器,适用于字符串、浮点数和整数isAlphaNumeric字段验证器,适用于字符串isInt字段验证器,适用于字符串和整数isFloat字段验证器,适用于字符串、浮点数和整数isString字段验证器,适用于字符串isObject字段验证器,适用于对象equals字段验证器,适用于任何给定的数据类型contains字段验证器,适用于字符串greaterThan字段验证器,适用于数字字符串、浮点数和整数greaterEqual字段验证器,适用于数字字符串、浮点数和整数lowerThan字段验证器,适用于数字字符串、浮点数和整数lowerEqual字段验证器,适用于数字字符串、浮点数和整数between字段验证器,适用于数字字符串、浮点数和整数isDate字段验证器,适用于日期字符串和实现 DateTimeInterface 接口的对象dateHasFormat字段验证器,适用于日期字符串和实现 DateTimeInterface 接口的对象dateEquals字段验证器,适用于日期字符串和实现 DateTimeInterface 接口的对象dateLowerThan字段验证器,适用于日期字符串和实现 DateTimeInterface 接口的对象dateLowerEqual字段验证器,适用于日期字符串和实现 DateTimeInterface 接口的对象dateGreaterThan字段验证器,适用于日期字符串和实现 DateTimeInterface 接口的对象dateGreaterEqual字段验证器,用于日期字符串和实现 DateTimeInterface 接口的对象dateBetween字段验证器,用于日期字符串和实现 DateTimeInterface 接口的对象
安装
$ composer require guyliangilsing/php-validation
重要:PHPValidation 需要 PHP 版本 8 或更高版本才能正常工作。
用法
获取验证器
可以通过 ValidatorBuilder 类获取验证器
use PHPValidation\Builders\ValidatorBuilder; use PHPValidation\Strategies\DefaultValidationStrategy; $strategy = new DefaultValidationStrategy(); $builder = new ValidatorBuilder($strategy); // Your configuration logic here... $validator = $builder->build();
验证器构建器有以下选项
use PHPValidation\Builders\ValidatorBuilder; use PHPValidation\Strategies\DefaultValidationStrategy; use PHPValidation\Validator; use function PHPValidation\Functions\required; $strategy = new DefaultValidationStrategy(); $builder = new ValidatorBuilder($strategy); // Configures the field validators for each array field $builder->setValidators([ 'field1' => [required()], ]); // Configures custom error messages for each array field validator $builder->setErrorMessages([ 'field1' => [ required()->getKey() => "My custom error message...", ] ]); // Passes a new validation handler/strategy to the actual validator $newStrategy = // Your custom strategy here... $builder->setStrategy($newStrategy); // Registers a new validator class that will be returned when you build the validator $builder->setValidatorClassName(Validator::class); $validator = $builder->build();
注意:构建器已经预先配置了策略和验证器类名,上面的示例只是列出所有可能的配置选项。
通过工厂
也可以通过默认工厂获取验证器
namespace PHPValidation\Factories\ValidatorFactory; $factory = new ValidatorFactory(); $validator = $factory->createDefaultValidator();
注意:可以通过继承它来向这个默认工厂类添加更多方法。
配置数组字段验证
在验证构建器中,必须设置一个数组来定义如何验证给定的数组。这使用以下结构
[
'fieldName' => [FieldValidatorInterface, FieldValidatorInterface, FieldValidatorInterface],
'nestedField' => [
'fieldName' => [FieldValidatorInterface, FieldValidatorInterface, FieldValidatorInterface],
]
]
结构本身非常简单。它只是一个通过键定义字段名称和通过实现 FieldValidatorInterface 接口的类定义字段验证的数组。也支持嵌套字段,您只需将键指向一个具有基本键 => array< FieldValidatorInterface > 结构的数组即可,这可以无限进行。
配置自定义错误消息
每个内置字段验证器都自带默认的错误消息。可以通过提供具有以下结构的数组来覆盖这些消息
[
'fieldName' => [
'fieldValidatorKey' => "Your custom error message..."
],
'nestedField' => [
'fieldName' => [
'fieldValidatorKey' => "Your custom error message..."
],
],
]
此结构需要一个字段名称键,该键指向一个数组,该数组具有字段验证键和一个错误消息作为键 => 值对。也支持嵌套字段,可以使用单个字段的结构的包装,在由键指向的数组中。
使用验证器
配置验证器构建器后,可以通过使用 build() 方法构建验证器
use PHPValidation\Builders\ValidatorBuilder; use PHPValidation\Strategies\DefaultValidationStrategy; $strategy = new DefaultValidationStrategy(); $builder = new ValidatorBuilder($strategy); // Your configuration logic here... $validator = $builder->build();
然后可以使用验证器验证一个数组
use PHPValidation\Builders\ValidatorBuilder; use PHPValidation\Strategies\DefaultValidationStrategy; use function PHPValidation\Functions\required; $strategy = new DefaultValidationStrategy(); $builder = new ValidatorBuilder($strategy); $builder->setValidators([ 'field1' => [required()], ]); $validator = $builder->build(); $isValid = $validator->isValid([]); // Will return false $errorMessages = $validator->getErrorMessages(); // Will return error messages
创建自定义字段验证器
创建自定义字段验证器非常简单。您只需实现 FieldValidatorInterface 接口即可
declare(strict_types=1); namespace PHPValidation\Fields; final class RequiredField implements FieldValidatorInterface { // Is used by the validation strategy and will skip this validator if it needs an existing field public function fieldNeedsToExist(): bool { return false; } // The unique key for this validator public function getKey(): string { return 'required'; } // Your validation logic goes here... public function isValid(bool $fieldExists, mixed $fieldData, array $givenData): bool { return $fieldExists; } // Your default error message goes here... public function getErrorMessage(): string { return 'This field is required'; } }
建议创建一个简单的函数来包装您的自定义验证器。PHPValidation 携带一些基本的内置验证器,它们以以下方式包装
declare(strict_types=1); namespace PHPValidation\Functions; use PHPValidation\Fields\FieldValidatorInterface; use PHPValidation\Fields\RequiredField; function required(): FieldValidatorInterface { return new RequiredField(); }
使用函数包装您的自定义验证器可以防止编写以下代码
use PHPValidation\Builders\ValidatorBuilder; use PHPValidation\Strategies\DefaultValidationStrategy; use PHPValidation\Validator; $strategy = new DefaultValidationStrategy(); $builder = new ValidatorBuilder($strategy); $builder->setValidators([ 'field1' => [new RequiredField(), new CustomValidator()], ]); $validator = $builder->build();
并且使最终代码更容易阅读
use PHPValidation\Builders\ValidatorBuilder; use PHPValidation\Strategies\DefaultValidationStrategy; use PHPValidation\Validator; use function PHPValidation\Functions\required; $strategy = new DefaultValidationStrategy(); $builder = new ValidatorBuilder($strategy); $builder->setValidators([ 'field1' => [required(), custom_validator()], ]); $validator = $builder->build();
可用的字段验证器
PHPValidation 携带一些内置字段验证器,应涵盖基本用例。
required
当添加时,此字段键必须存在于数组中。
$builder->setValidators([ 'field' => [required()], ]);
notEmpty
当添加时,并且字段存在,并且字段类型为 string 或 array,它不能为空或仅包含空白。
$builder->setValidators([ 'field' => [notEmpty()], ]);
isArray
当添加时,并且字段存在,它必须是类型 array。
$builder->setValidators([ 'field' => [isArray()], ]);
hasKeys
当添加时,并且字段存在,并且字段类型为 array,它必须具有所有指定的键。
$builder->setValidators([ 'field' => [hasKeys('key1', 'key2', 'key3')], ]);
hasValues
当添加时,并且字段存在,并且字段类型为 array,它必须具有所有指定的值。
$builder->setValidators([ 'field' => [hasValues(['value1', 'value2', 'value3'])], ]);
confirmValues
当添加时,并且字段存在,字段值必须等于另一个字段的值。当指定当前字段必须匹配的数组字段值时,使用点符号来表示键树: key1.nestedKey1 翻译为以下 PHP 数组
[
'key1' => [
'nestedKey1' => // YOUR VALUE HERE...
],
]
$builder->setValidators([ 'field1' => [confirmValues('field2')], // Targets the key on the first array level 'field2' => [confirmValues('field2.nestedField1')], // Targets the key on the second array level ]);
in
当添加时,并且字段存在,并且字段类型为 string、int、float、bool 或 array,它只能包含所列值之一。
注意:当此验证器传入一个数组值时,它将仅验证数组的第一个级别。
$builder->setValidators([ 'field' => [in(['option1', 'option2', 'option3'])], ]);
notIn
当添加时,并且字段存在,并且字段类型为 string、int、float 或 bool,它不能包含所列值之一。
$builder->setValidators([ 'field' => [notIn(['option1', 'option2', 'option3'])], ]);
minLength
当添加时,并且字段存在,并且字段类型为 string,它必须具有最小字符数。
$builder->setValidators([ 'field' => [minLength(5)], ]);
maxLength
当添加字段且该字段存在,并且字段类型为 string 时,它不能超过一定数量的字符。
$builder->setValidators([ 'field' => [maxLength(10)], ]);
minCount
当添加字段且该字段存在,并且字段类型为 array 时,它必须包含一定数量的值。
$builder->setValidators([ 'field' => [minCount(2)], ]);
maxCount
当添加字段且该字段存在,并且字段类型为 array 时,它不能超过一定数量的值。
$builder->setValidators([ 'field' => [maxCount(4)], ]);
当添加字段且该字段存在,并且字段类型为 string 时,它将检查是否符合 RFC 5322 标准的电子邮件地址。
$builder->setValidators([ 'field' => [email()], ]);
phoneNumber
当添加字段且该字段存在,并且字段类型为 string 时,它将检查是否符合有效的国际电话号码。
注意:此验证器不接受任何字符和/或空格分隔的电话号码。
注意:可能最好创建自己的电话号码验证器,因为电话号码可能因国家/地区而大不相同。
$builder->setValidators([ 'field' => [phoneNumber()], ]);
isAlphabetic
当添加字段且该字段存在,并且字段类型为 string 时,它将检查其值是否只包含普通、非特殊字符和空白。
$builder->setValidators([ 'field' => [isAlphabetic()], ]);
isNumeric
当添加字段且该字段存在,并且字段类型为 string、float 或 int 时,它将检查给定值是否为数值。
$builder->setValidators([ 'field' => [isNumeric()], ]);
isAlphaNumeric
当添加字段且该字段存在,并且字段类型为 string 时,它将检查给定值是否只包含普通、非特殊字符、数字和空白。验证器还支持白名单额外字符。
$builder->setValidators([ 'normalField' => [isAlphaNumeric()], 'extraField' => [isAlphaNumeric(['.', ',', '\\', '[', ']'])], // Whitelists each individual character within the array ]);
isInt
当添加字段且该字段存在,并且字段类型为 string 或 int 时,它将检查给定值是否可以转换为整数,并且因此是整数。
$builder->setValidators([ 'field' => [isInt()], ]);
isFloat
当添加字段且该字段存在,并且字段类型为 string、float 或 int 时,它将检查给定值是否可以在不丢失任何数据的情况下转换为浮点数,并且因此是浮点数。
$builder->setValidators([ 'field' => [isFloat()], ]);
isString
当添加字段且该字段存在时,它将检查给定值是否为 string 类型。
$builder->setValidators([ 'field' => [isString()], ]);
isObject
当添加字段且该字段存在时,它将检查给定值是否为 object 类型。
$builder->setValidators([ 'field' => [isObject()], ]);
objectOfType
当添加字段且该字段存在,并且字段类型为 object 时,它将检查给定值是否具有期望的对象类型。
$builder->setValidators([ 'field' => [objectOfType(DateTime::clas)], ]);
equals
当添加字段且该字段存在时,它将检查给定值是否与字段值匹配。此验证器支持严格和非严格值验证。
$builder->setValidators([ 'nonStrictField' => [equals('non-strict', false)], 'strictField' => [equals('strict', true)], ]);
contains
当添加字段且该字段存在,并且字段类型为 string 时,它将检查给定值是否包含特定的子字符串。
$builder->setValidators([ 'field' => [contains('substring')], ]);
greaterThan
当添加字段且该字段存在,并且字段类型为 string、float 或 int 时,它将检查给定值是否大于字段值。
$builder->setValidators([ 'field' => [greaterThan(30)], ]);
greaterEqual
当添加字段且该字段存在,并且字段类型为 string、float 或 int 时,它将检查给定值是否大于或等于字段值。
$builder->setValidators([ 'field' => [greaterEqual(30)], ]);
lowerThan
当添加字段且该字段存在,并且字段类型为 string、float 或 int 时,它将检查给定值是否小于字段值。
$builder->setValidators([ 'field' => [lowerThan(30)], ]);
lowerEqual
当添加字段且该字段存在,并且字段类型为 string、float 或 int 时,它将检查给定值是否小于或等于字段值。
$builder->setValidators([ 'field' => [lowerEqual(30)], ]);
between
当添加字段且该字段存在,并且字段类型为 string、float 或 int 时,它将检查给定值是否介于两个给定值之间。
$builder->setValidators([ 'field' => [between(0, 100)], ]);
isDate
当添加字段且该字段存在,并且字段类型为 string 或实现 DateTimeInterface 接口时,它将检查该字段是否为日期字符串或实现 DateTimeInterface 接口的对象。
注意:此字段使用 php 的 strtotime() 函数来检查字符串是否确实是日期字符串。
$builder->setValidators([ 'field' => [isDate()], ]);
dateHasFormat
当添加字段时,如果该字段存在并且字段类型为以下类型 string 或实现了 DateTimeInterface 接口,则会检查该字段是否使用了指定的 PHP 日期时间格式。
注意:建议仅使用此验证器与日期字符串。实现了 DateTimeInterface 接口的对象始终有效,因为它们会内部转换为指定格式的字符串。
$builder->setValidators([ 'field' => [dateHasFormat('Y-m-d')], ]);
dateEquals
当添加字段时,如果该字段存在并且字段类型为以下类型 string 或实现了 DateTimeInterface 接口,则会检查字段值是否等于预先确定的日期对象。
$builder->setValidators([ 'field' => [dateEquals(DateTime::createFromFormat('Y-m-d', '2000-12-31'), 'Y-m-d')], ]);
dateLowerThan
当添加字段时,如果该字段存在并且字段类型为以下类型 string 或实现了 DateTimeInterface 接口,则会检查给定值是否小于字段值。
$builder->setValidators([ 'field' => [dateLowerThan(DateTime::createFromFormat('Y-m-d', '2000-12-31'), 'Y-m-d')], ]);
dateLowerEqual
当添加字段时,如果该字段存在并且字段类型为以下类型 string 或实现了 DateTimeInterface 接口,则会检查给定值是否小于或等于字段值。
$builder->setValidators([ 'field' => [dateLowerEqual(DateTime::createFromFormat('Y-m-d', '2000-12-31'), 'Y-m-d')], ]);
dateGreaterThan
当添加字段时,如果该字段存在并且字段类型为以下类型 string 或实现了 DateTimeInterface 接口,则会检查给定值是否大于字段值。
$builder->setValidators([ 'field' => [dateGreaterThan(DateTime::createFromFormat('Y-m-d', '2000-12-31'), 'Y-m-d')], ]);
dateGreaterEqual
当添加字段时,如果该字段存在并且字段类型为以下类型 string 或实现了 DateTimeInterface 接口,则会检查给定值是否大于或等于字段值。
$builder->setValidators([ 'field' => [dateGreaterEqual(DateTime::createFromFormat('Y-m-d', '2000-12-31'), 'Y-m-d')], ]);
dateBetween
当添加字段时,如果该字段存在并且字段类型为以下类型 string 或实现了 DateTimeInterface 接口,则会检查给定值是否在两个给定日期之间。
$dateMin = DateTime::createFromFormat('Y-m-d', '2000-12-29'); $dateMax = DateTime::createFromFormat('Y-m-d', '2000-12-30'); $builder->setValidators([ 'field' => [dateBetween($dateMin, $dateMax, 'Y-m-d')], ]);