guyliangilsing/php-validation

一个简单的验证库,允许您为数据编写自定义验证器。

1.3.0 2023-12-06 16:33 UTC

This package is auto-updated.

Last update: 2024-09-06 18:22:12 UTC


README

一个简单的验证库,允许您为数据编写自定义验证器。

目录

特性

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

当添加时,并且字段存在,并且字段类型为 stringarray,它不能为空或仅包含空白。

$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

当添加时,并且字段存在,并且字段类型为 stringintfloatboolarray,它只能包含所列值之一。

注意:当此验证器传入一个数组值时,它将仅验证数组的第一个级别。

$builder->setValidators([
    'field' => [in(['option1', 'option2', 'option3'])],
]);

notIn

当添加时,并且字段存在,并且字段类型为 stringintfloatbool,它不能包含所列值之一。

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

email

当添加字段且该字段存在,并且字段类型为 string 时,它将检查是否符合 RFC 5322 标准的电子邮件地址。

$builder->setValidators([
    'field' => [email()],
]);

phoneNumber

当添加字段且该字段存在,并且字段类型为 string 时,它将检查是否符合有效的国际电话号码。

注意:此验证器不接受任何字符和/或空格分隔的电话号码。
注意:可能最好创建自己的电话号码验证器,因为电话号码可能因国家/地区而大不相同。

$builder->setValidators([
    'field' => [phoneNumber()],
]);

isAlphabetic

当添加字段且该字段存在,并且字段类型为 string 时,它将检查其值是否只包含普通、非特殊字符和空白。

$builder->setValidators([
    'field' => [isAlphabetic()],
]);

isNumeric

当添加字段且该字段存在,并且字段类型为 stringfloatint 时,它将检查给定值是否为数值。

$builder->setValidators([
    'field' => [isNumeric()],
]);

isAlphaNumeric

当添加字段且该字段存在,并且字段类型为 string 时,它将检查给定值是否只包含普通、非特殊字符、数字和空白。验证器还支持白名单额外字符。

$builder->setValidators([
    'normalField' => [isAlphaNumeric()],
    'extraField' => [isAlphaNumeric(['.', ',', '\\', '[', ']'])], // Whitelists each individual character within the array
]);

isInt

当添加字段且该字段存在,并且字段类型为 stringint 时,它将检查给定值是否可以转换为整数,并且因此是整数。

$builder->setValidators([
    'field' => [isInt()],
]);

isFloat

当添加字段且该字段存在,并且字段类型为 stringfloatint 时,它将检查给定值是否可以在不丢失任何数据的情况下转换为浮点数,并且因此是浮点数。

$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

当添加字段且该字段存在,并且字段类型为 stringfloatint 时,它将检查给定值是否大于字段值。

$builder->setValidators([
    'field' => [greaterThan(30)],
]);

greaterEqual

当添加字段且该字段存在,并且字段类型为 stringfloatint 时,它将检查给定值是否大于或等于字段值。

$builder->setValidators([
    'field' => [greaterEqual(30)],
]);

lowerThan

当添加字段且该字段存在,并且字段类型为 stringfloatint 时,它将检查给定值是否小于字段值。

$builder->setValidators([
    'field' => [lowerThan(30)],
]);

lowerEqual

当添加字段且该字段存在,并且字段类型为 stringfloatint 时,它将检查给定值是否小于或等于字段值。

$builder->setValidators([
    'field' => [lowerEqual(30)],
]);

between

当添加字段且该字段存在,并且字段类型为 stringfloatint 时,它将检查给定值是否介于两个给定值之间。

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