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')], ]);