如何处理不同的错误级别

3.4 版本
维护中的版本

有时,你可能希望基于某些规则来显示不同的约束验证之错误信息。例如,你为新用户建立了一个注册用表单,用户需要输入身份信息和用户凭据来完成注册。他们不得不输入用户名和一个安全密码,但是输入银行账户信息则是可选的。尽管如此,如果用户在该字段输入了信息,你仍然要确保这些可选字段有效,只是要以不同方式来显示错误。

实现此种行为的过程,包括两个步骤:

  1. 给验证约束提供不同的错误级别;

  2. 根据所配置的错误级别来自定义你的错误信息;

1. 分配错误级别 

使用payload选项去为每个约束配置错误级别:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// src/AppBundle/Entity/User.php
namespace AppBundle\Entity;
 
use Symfony\Component\Validator\Constraints as Assert;
 
class User
{
    /**
     * @Assert\NotBlank(payload = {"severity" = "error"})
     */
    protected $username;
 
    /**
     * @Assert\NotBlank(payload = {"severity" = "error"})
     */
    protected $password;
 
    /**
     * @Assert\Iban(payload = {"severity" = "warning"})
     */
    protected $bankAccountNumber;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# src/AppBundle/Resources/config/validation.yml
AppBundle\Entity\User:
    properties:
        username:
            - NotBlank:
                payload:
                    severity: error
        password:
            - NotBlank:
                payload:
                    severity: error
        bankAccountNumber:
            - Iban:
                payload:
                    severity: warning
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!-- src/AppBundle/Resources/config/validation.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping http://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
 
    <class name="AppBundle\Entity\User">
        <property name="username">
            <constraint name="NotBlank">
                <option name="payload">
                    <value key="severity">error</value>
                </option>
            </constraint>
        </property>
        <property name="password">
            <constraint name="NotBlank">
                <option name="payload">
                    <value key="severity">error</value>
                </option>
            </constraint>
        </property>
        <property name="bankAccountNumber">
            <constraint name="Iban">
                <option name="payload">
                    <value key="severity">warning</value>
                </option>
            </constraint>
        </property>
    </class>
</constraint-mapping>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// src/AppBundle/Entity/User.php
namespace AppBundle\Entity;
 
use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Validator\Constraints as Assert;
 
class User
{
    public static function loadValidatorMetadata(ClassMetadata $metadata)
    {
        $metadata->addPropertyConstraint('username', new Assert\NotBlank(array(
            'payload' => array('severity' => 'error'),
        )));
        $metadata->addPropertyConstraint('password', new Assert\NotBlank(array(
            'payload' => array('severity' => 'error'),
        )));
        $metadata->addPropertyConstraint('bankAccountNumber', new Assert\Iban(array(
            'payload' => array('severity' => 'warning'),
        )));
    }
}

2. 自定义错误信息模板 

当对 User 对象验证失败时,你可以使用 getConstraint()方法来取出引发特定失败的约束。每个约束都会暴露附加的payload作为一个公有属性:

1
2
3
4
5
6
// a constraint validation failure, instance of
// Symfony\Component\Validator\ConstraintViolation
// 约束在验证时失败时的ConstraintViolation实例
$constraintViolation = ...;
$constraint = $constraintViolation->getConstraint();
$severity = isset($constraint->payload['severity']) ? $constraint->payload['severity'] : null;

比如,你可以利用它来定制 form_errors 区块,以便severity(错误级别)作为附加的HTML class被添加:

1
2
3
4
5
6
7
8
9
10
11
12
{%- block form_errors -%}
    {%- if errors|length > 0 -%}
    <ul>
        {%- for error in errors -%}
            {% if error.cause.constraint.payload.severity is defined %}
                {% set severity = error.cause.constraint.payload.severity %}
            {% endif %}
            <li{% if severity is defined %} class="{{ severity }}"{% endif %}>{{ error.message }}</li>
        {%- endfor -%}
    </ul>
    {%- endif -%}
{%- endblock form_errors -%}

关于表单自定义输出的更多信息,参考 如何自定义表单渲染

本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。

登录symfonychina 发表评论或留下问题(我们会尽量回复)