dcp/validator

提供表单验证功能。

v1.0.1 2016-08-25 21:28 UTC

This package is not auto-updated.

Last update: 2024-09-20 02:39:46 UTC


README

DCP-Validator提供了一个简单的API用于数据和表单验证。

该项目的设计目标始终是简洁、简单、可扩展和可测试。

Build Status Coverage Status

入门指南

列表中的第一项是将包安装到您的应用程序中。

最简单、也推荐的方式是通过composer安装此包。

只需在您的项目中创建一个composer.json文件

{
    "require": {
        "dcp/validator": "1.0.*"
    }
}

然后,运行composer命令来安装DCP-Validator

$ composer install

或者,您可以克隆仓库并手动安装包。

基本用法

创建验证器

首先需要做的是创建验证器本身。

use DCP\Form\Validation\Validator;

$validator = new Validator();

添加规则

一旦创建了验证器,您可能希望添加验证规则,使验证器能够做一些工作。

use DCP\Form\Validation\Validator;
use DCP\Form\Validation\RuleSet;
use DCP\Form\Validation\Rule;
use DCP\Form\Validation\Constraint;

$ruleSet = (new RuleSet())
    ->add(
        (new Rule())
            ->setFieldName('username')
            ->setMessage('Username cannot be blank')
            ->addConstraint(Constraint::notBlank())
    )
;

$validator = new Validator();
$validator->setRuleSet($ruleSet);

或者,您可以直接通过验证器本身添加规则,以节省输入时间,而不创建显式的规则集。

use DCP\Form\Validation\Validator;
use DCP\Form\Validation\Rule;
use DCP\Form\Validation\Constraint;

$validator = new Validator();
$validator->addRule(
    (new Rule())
        ->setFieldName('username')
        ->setMessage('Username cannot be blank')
        ->addConstraint(Constraint::notBlank())
);

验证

由于已经向验证器中添加了规则,现在是时候将验证器投入使用了。

要检查表单是否有效,只需调用validate()方法。validate()方法将返回一个结果对象,您可以在其中检查表单是否有效,如果不有效,则会显示哪些错误。

use DCP\Form\Validation\Validator;
use DCP\Form\Validation\Rule;
use DCP\Form\Validation\Constraint;

$validator = new Validator();
$validator->addRule(
    (new Rule())
        ->setFieldName('username')
        ->setMessage('Username cannot be blank')
        ->addConstraint(Constraint::notBlank())
);

$form = [
    'username' => 'test_user'
];

$result = $validator->validate($form);

if ($result->isValid()) {
    echo 'Hooray, the form is valid!';
}

您还可以验证类实例的数据

use DCP\Form\Validation\Validator;
use DCP\Form\Validation\Rule;
use DCP\Form\Validation\Constraint;

class MyForm
{
    protected $username;

    public function getUsername()
    {
        return $this->username;
    }

    public function setUsername($username)
    {
        $this->username = $username;
    }
}

$validator = new Validator();
$validator->addRule(
    (new Rule())
        ->setFieldName('username')
        ->setMessage('Username cannot be blank')
        ->addConstraint(Constraint::notBlank())
);

$form = new MyForm();
$form->setUsername('test_user');

$result = $validator->validate($form);

if ($result->isValid()) {
    echo 'Hooray, the form is valid!';
}

详细用法

规则对象

规则对象是魔法发生的地方。在这里,您可以决定哪些字段需要验证,字段应遵守的约束,以及当规则验证失败时显示的错误信息。

规则对象的最简单形式只是一个字段名、错误信息和一些约束。

(new Rule())
    ->setFieldName('username')
    ->setMessage('Username must not be blank')
    ->addConstraint(Constraints::notBlank())
;

请注意,为规则设置消息不是强制性的。

(new Rule())->getMessage();
// This field failed validation

在规则对象内部,您可以为验证步骤设置所有功能,如前提条件、过滤器、约束。

完整示例

(new Rule())
    ->setFieldName('password_repeat')
    ->setMessage('Passwords must match')
    ->addPrerequisite(Prerequisites::notBlank(new FieldReference('password')))
    ->addFilter(Filters::trim())
    ->addConstraint(Constraints::notBlank())
;

规则集对象

规则集对象只是一个包含规则对象的集合。它的主要目的是为验证器持有验证规则的定义。

$ruleSet = (new RuleSet())
    ->add(
        (new Rule())
            ->setFieldName('username')
            ->setMessage('Username cannot be blank')
            ->addConstraint(Constraint::notBlank())
    )
;

$validator = new Validator();
$validator->setRuleSet($ruleSet);

请记住,规则集不是验证器使用的必需品。验证器上有一个便捷方法允许您直接向验证器添加规则,绕过显式创建规则集。然而,规则集仍在幕后使用。

$validator = new Validator();
$validator->addRule(
    (new Rule())
        ->setFieldName('username')
        ->setMessage('Username cannot be blank')
        ->addConstraint(Constraint::notBlank())
);

约束

约束允许您验证字段中的数据是否符合您的期望。

(new Rule())
    ->setFieldName('email_address')
    ->addConstraint(Constraints::notBlank())
    ->addConstraint(Constraints::formatEmail())
;
// This will ensure that the email address is not blank, and matches a valid email format (e.g. user@example.com)

默认提供了一些约束

  • Constraints::notBlank()
  • Constraints::formatEmail()
  • Constraints::formatDigits()
  • Constraints::formatNumeric()
  • Constraints::formatRegex($regex)
    • 正则表达式格式是PCRE,如 '/(T|t)est/'
  • Constraints::isBlank()
  • Constraints::mustMatch($value)
    • 值可以是字面值或字段引用

过滤器

过滤器是在验证规则之前对数据进行修改的一种方式。这通常用于修剪输入,或将字段大写或小写。

(new Rule())
    ->setFieldName('username')
    ->addFilter(Filters::trim())
    ->addFilter(Filters::toLowerCase())
;
// This will trim and lowercase the username field prior to validating the rule.

默认提供了一些过滤器

  • Filters::trim()
  • Filters::toLowerCase()
  • Filters::toUpperCase()

前提条件

先决条件允许您确保在满足一系列定义的准则之后,才会验证规则。

一个很好的例子是要求如果一个字段包含某个特定的值,则必须填写该字段。

/*
 * Assume the form has a field named 'send_me_an_email_newsletter' that is a checkbox with a value
 * of 'yes'. When checked, the user is required to enter their email address to receive email newsletters.
*/

(new RuleSet())
    ->add(
        (new Rule())
            ->setFieldName('email')
            ->setMessage('Email is not valid')
            ->addPrerequisite(Prerequisites::mustMatch(new FieldReference('send_me_an_email_newsletter'), 'yes'))
            ->addFilter(Filters::trim())
            ->addConstraint(Constraints::notBlank())
            ->addConstraint(Constraints::formatEmail())
    )
;

请注意,Prerequisites::mustMatch() 也接受一个字段引用作为其第二个参数,因此您可以在验证给定规则之前检查两个字段是否匹配。在这方面,它类似于 Constraints::mustMatch()。

默认提供了一些先决条件

  • Prerequisites::notBlank(FieldReference $reference)
  • Prerequisites::isBlank(FieldReference $reference)
  • Prerequisites::mustMatch(FieldReference $reference, $value)
    • 值可以是字面值或字段引用

字段引用

字段引用允许您在验证时创建对另一个字段值的引用。这在您有一个需要两个字段值匹配的表单时特别有用。

(new RuleSet())
    ->add(
        (new Rule())
            ->setFieldName('password')
            ->setMessage('Password must not be blank')
            ->addFilter(Filters::trim())
            ->addConstraint(Constraints::notBlank())
    )
    ->add(
        (new Rule())
            ->setFieldName('password_repeat')
            ->setMessage('Passwords do not match')
            // Do not validate unless the password field is not blank.
            ->addPrerequisite(Prerequisites::notBlank(new FieldReference('password')))
            ->addFilter(Filters::trim())
            // This field must match the password field's value.
            ->addConstraint(Constraints::mustMatch(new FieldReference('password')))
    )
;

结果对象

结果对象由 Validator#validate() 方法返回。它可以用来确定表单验证是否成功,或者是否有任何错误处理表单。

结果对象最基本的使用是检查验证是否成功

$result = $validator->validate($form);

if ($result->isValid()) {
    echo 'Hooray, the form is valid!';
} else {
    echo 'Better luck next time.';
}

对象的高级使用包括检查特定字段是否有错误

$result = $validator->validate($form);

if (!$result->isValid()) {
    if ($result->fieldHasError('username')) {
        echo 'Username field had a validation error.';
    }
}

甚至可以检索在验证期间抛出的错误消息。这有助于告诉用户发生了什么错误,以及如何修复它

$result = $validator->validate($form);

if (!$result->isValid()) {
    if ($result->fieldHasError('username')) {
        echo "Username had a validation error. Wonder what it was:\n";
        echo $result->getError('username');
    }
}

自定义约束/过滤器/先决条件

所有约束、过滤器、和先决条件都是可调用的。提供的默认实现是闭包。

// From the Constraints class
public static function notBlank()
{
    return function ($data) {
        return strlen($data) > 0;
    };
}

因此,用户可以很容易地通过定义自定义回调来构建自己的验证器、过滤器或先决条件。

$steveCallback = function ($data) {
    if ($data === 'steve') {
        return true;
    }

    return false;
};

(new Rule())
    ->setFieldName('username')
    ->setMessage('You are definitely not steve')
    ->addConstraint($steveCallback)
;

如果用户想要创建可重用的回调,他们可以在类中定义回调,或者扩展一个适当的默认类。

class MyConstraints extends Constraints
{
    public static function isSteve()
    {
        return function ($data) {
            if ($data === 'steve') {
                return true;
            }

            return false;
        };
    }
}

(new Rule())
    ->setFieldName('username')
    ->setMessage('You are definitely not steve')
    ->addConstraint(MyConstraints::isSteve())
;

自定义回调适用于所有基于回调的系统,如约束、过滤器、和先决条件。

验证器组

DCP-Validator 通过验证器组允许部分表单验证。当表单跨越多个不同页面时,这特别有用。

通过调用 Rule#addValidationGroup 为规则设置验证组。

(new Rule())
    ->setFieldName('username')
    ->setMessage('Please enter a username')
    ->addConstraint(Constraints::notBlank())
    ->addValidationGroup('page_1')
;

当验证表单时,您可以指定要验证的验证器组。

$rules = (new RuleSet())
    ->add(
        (new Rule())
            ->setFieldName('username')
            ->setMessage('Please enter a username')
            ->addConstraint(Constraints::notBlank())
            ->addValidationGroup('page_1')
    )
    ->add(
        (new Rule())
            ->setFieldName('password')
            ->setMessage('Please enter a password')
            ->addConstraint(Constraints::notBlank())
            ->addValidationGroup('page_2')
    )
;

$form = [
    'username' => '',
    'password' => ''
];

$validator = new Validator();
$validator->setRuleSet($rules);

$validator->validate('page_2');
// This will only validate the password field.

贡献

如果您想为 DCP-Validator 贡献,您可以通过以下两种方式之一进行

  • 提交您发现的错误或改进项目的功能。
  • 分支存储库,添加一些功能,然后提交一个拉取请求。

测试

DCP-Validator 使用 PHPUnit 3.7.x 进行自动化测试。

代码库的所有更改都伴随着单元测试。