smwcentral/validator

SMW Central 表单验证库

v1.0.0 2021-01-10 22:13 UTC

This package is auto-updated.

Last update: 2024-09-11 06:14:28 UTC


README

Latest Stable Version GitHub Actions License

由SMW Central(SMW Central)使用的轻量级表单验证组件。旨在以最小的运行时成本提供友好且灵活的API。

安装

使用Composer安装。需要PHP 7.3+和JSON以及mbstring扩展。

$ composer require smwcentral/validator

示例

use SMWCentral\Validation\Validator;

$validator = new Validator($_POST);
$recipient = $validator->string('recipient')->value();
$subject = $validator->string('subject')->between(1, 255)->value();
$text = $validator->string('text')->between(1, 65535)->value();

$isRecipientValid = false; /* validate manually somehow */

if(!$isRecipientValid){
    $validator->errors()->add('recipient', 'not_found');
}

if($validator->passes()){
    // use data
}

用法

基本用法

构建一个Validator对象,传入一个可能被验证的字段数组,通常是$_POST

use SMWCentral\Validation\Validator;

$validator = new Validator($_POST);

使用retrieve()创建一个表示给定字段的Variable对象。默认情况下,字段是必需的,如果没有值存在,将创建一个验证错误。传入第二个参数以指定默认值。

$id = $validator->retrieve('id'); // required
$description = $validator->retrieve('description', ''); // will default to an empty string

每个Variable上调用的第一个验证规则必须指定数据类型。在指定类型之前,所有其他验证规则都会抛出LogicException

字段值将被强制转换为给定的数据类型。如果无法完成转换,将添加一个验证错误。

$variable->string();
$variable->integer();
$variable->float();
$variable->boolean();
$variable->array();

指定数据类型后,根据需要调用其他验证规则。可以在Variable上链式调用所有方法。

处理值“大小”的验证规则使用整数和浮点数的数字本身,或字符串和数组的长度。

$variable->size($exactSize);
$variable->min($min);
$variable->max($max);
$variable->between($min, $max);
$variable->in($arrayOfPossibleValues, $useStrictComparison = true);

最后,使用value()获取字段的值。它保证是Variable指定的数据类型(如果字段是可选的,则为null)。在检查验证结果之前,不一定满足其他验证规则。

$value = $variable->value();

使用Validator上的passes()方法检查是否所有验证规则都已成功。使用errors()获取包含每个字段错误的MessageBag

if($validator->passes()){
    // all values are guaranteed to follow the validation rules
    // continue form action
}else{
    $errors = $validator->errors();

    // show errors to the user
}

简写类型

Validator有简写方法,可以同时检索变量并设置其数据类型。您几乎总是使用这些方法而不是retrieve()

$validator->string($name, $default = null);
$validator->integer($name, $default = null);
$validator->float($name, $default = null);
$validator->boolean($name, $default = null);
$validator->array($name, $default = null);

// is equivalent to

$validator->retrieve($name, $default = null)->string();
$validator->retrieve($name, $default = null)->integer();
$validator->retrieve($name, $default = null)->float();
$validator->retrieve($name, $default = null)->boolean();
$validator->retrieve($name, $default = null)->array();

一个完整的链通常如下所示

// Field `description` is an optional string between 0 and 65535
// characters. Its value will be stored in `$description`.
$description = $validator->string('description', '')->between(0, 65535)->value();

中断

默认情况下,将所有验证规则调用到一个Variable上。最终,可能有多个验证错误。使用bail()方法忽略在第一个失败后对Variable的验证规则。

// If the value is shorter than 5 characters, both `min()` and `between()`
// will create a validation error.
$variable->min(5)->between(8, 10)->value();

// If the value is shorter than 5 characters, only `min()` will create a
// validation error. `between()` (and anything after it) will be ignored.
$variable->bail()->min(5)->between(8, 10)->value();

消息包

验证错误收集在MessageBag中,可以通过Validatorerrors()方法访问。MessageBag可以存储任意数量的字段上的任意数量的Message对象。

$errors = $validator->errors();

// Methods that check all Messages
$errors->all();
$errors->count();
$errors->isEmpty();

// Methods that operate on specific fields
$errors->except(['fields', 'to', 'exclude']);
$errors->get('field');
$errors->getFirst('field');

// `MessageBag`s can be counted and encoded to JSON
count($errors);
json_encode($errors);

手动验证

Variable只提供基本的验证规则。您通常会进一步验证数据。使用value()检索类型转换后的字段值,然后运行所需的任何逻辑。使用MessageBagadd()方法添加自己的验证错误。

为了对验证错误有更精细的控制(例如,提供额外的参数),您也可以将Message实例传递给errors()->add()

use SMWCentral\Validation\Message;

$recipient = $validator->string('recipient')->value();

$recipientID = findUserID($recipient);

if(!$recipientID){
    $validator->errors()->add('recipient', 'not_found');

    // is equivalent to

    $validator->errors()->add('recipient', new Message('recipient', 'not_found'));
}

if($validator->passes()){
    // manual validation has succeeded
}

CSRF令牌

Validatorpasses()方法可以自动检查CSRF令牌。要启用此功能,将Validator::$tokenProvider设置为实现了ITokenProvider接口的自定义类的实例。

如果已配置令牌提供程序,则可以使用passes(false)跳过令牌验证。

use SMWCentral\Validation\{ITokenProvider, Validator};

Validator::$tokenProvider = new class implements ITokenProvider {
    public function getTokenKey(Validator $validator): string {
        // the name of the field that should contain the token
        return 'token';
    }

    public function getTokenValue(Validator $validator): string {
        // the expected value of the token
        return $_SESSION['token'];
    }
};

消息

验证错误由Message对象表示。

$message = $validator->errors()->getFirst('field');

echo $message;

// is equivalent to

echo $message->getTranslatedMessage();

内部,消息只包含稍后传递给消息解析器以构建人性友好消息的键。此包包括一个基本的默认解析器。

在大多数情况下,您希望使用自己的解析器。将 Message::$resolver 设置为实现了 IMessageResolver 接口的自定义类实例。检查 src/DefaultMessageResolver.php 中的 getMessages() 方法,查看验证器将使用哪些消息键。

use SMWCentral\Validation\{Message, MessageResolver};

Message::$resolver = new class implements IMessageResolver {
    public function resolveMessage(string $field, string $key, array $args): string {
        return "{$field}: {$key}";
    }
};

请注意,Message 维护自己的字段名称副本,这不一定与 MessageBag 中拥有 Message 的字段名称相同。

传递给 resolveMessage()$args 数组包含一组任意额外的参数。某些验证规则会将这些参数提供给它们的消息。例如,between() 规则将添加 minmax 参数。您还可以使用验证器的 retrieve() 方法和其缩写形式的第三个参数向任何 Variable 提供自定义参数。

$validator->string('name', null, ['context' => 'username'])->value();

当手动添加验证错误时,您可以创建一个 Message 来提供参数。

use SMWCentral\Validation\Message;

$validator->errors()->add('recipient', new Message('recipient', 'not_found', ['context' => 'private_message']));

默认消息解析器将直接将字段名称包含在消息中。为确保创建连贯的消息,您可以传递一个名为 field 的参数来覆盖名称。

$validator->string('new_pass')->min(8);
// DefaultMessageResolver could produce: The new_pass must have at least 8 characters.

$validator->string('new_pass', null, ['field' => 'new password'])->min(8);
// DefaultMessageResolver could produce: The new password must have at least 8 characters.

当然,您需要在自己的消息解析器中实现这种逻辑。

简写配置

您可以使用 Validator::configure() 同时设置消息解析器和令牌提供者。

Validator::configure($messageResolver, $tokenProvider);

如果其中一个参数传递为 null,则将被忽略。

测试

测试位于 tests 目录,并使用 PHPUnit。使用 vendor/bin/phpunit tests 运行。

许可证

MIT 许可证 下发布。

致谢

Telinc1 构建和维护。SMW Central 是 Noivern 的财产。