Validation


La validation est une tâche extrêmement courante dans les programmes web. Les données saisies dans le formulaire nécessitent une validation. Les données doivent également être validées lorsqu'elles sont écrites dans une base de données ou transférées vers un service Web.

Symfony est livré avec un composant Validator, qui rend le travail de vérification simple et transparent. Ce composant est basé sur la JSR303 Bean Validation Spécification.

Bases de la vérification

La meilleure façon de comprendre la vérification est de la voir en action. Avant de commencer, supposons que vous créiez un objet PHP natif utilisé quelque part dont votre programme a besoin : Le but de la vérification est de vous dire si les données contenues dans l'objet sont valides. Pour ce faire, vous devez configurer une liste de règles (appelées

constraints/constraints

) que l'objet doit suivre pour être valide. Ces règles peuvent être spécifiées dans différents formats (YAML, XML, annotations ou PHP).
Par exemple, pour vous assurer que l'attribut $name n'est pas vide, ajoutez le contenu suivant :

// src/AppBundle/Entity/Author.phpnamespace AppBundle\Entity; class Author{
    public $name;}
PHP:// src/AppBundle/Entity/Author.php // ...use Symfony\Component\Validator\Mapping\ClassMetadata;use Symfony\Component\Validator\Constraints\NotBlank; class Author{
    public $name;     public static function loadValidatorMetadata(ClassMetadata $metadata)
    {
        $metadata->addPropertyConstraint('name', new NotBlank());
    }}
XML:<!-- 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\Author">
        <property name="name">
            <constraint name="NotBlank" />
        </property>
    </class></constraint-mapping>
YAML:# src/AppBundle/Resources/config/validation.ymlAppBundle\Entity\Author:
    properties:
        name:
            - NotBlank: ~

$name 不为空,添加以下内容:

Annotations:// src/AppBundle/Entity/Author.php // ...use Symfony\Component\Validator\Constraints as Assert; class Author{
    /**
     * @Assert\NotBlank()
     */
    public $name;}
// ...use Symfony\Component\HttpFoundation\Response;use AppBundle\Entity\Author; // ...public function authorAction(){
    $author = new Author();     // ... do something to the $author object
    // ... 对 $author 对象做一些事     $validator = $this->get('validator');
    $errors = $validator->validate($author);     if (count($errors) > 0) {
        /*
         * Uses a __toString method on the $errors variable which is a
         * ConstraintViolationList object. This gives us a nice string
         * for debugging.
         * 对 $errors 变量,即 ConstraintViolationList 对象,使用 __toString 方法。
         * 这给了我们一个美观的字符串用于调试。
         */
        $errorsString = (string) $errors;         return new Response($errorsString);
    }     return new Response('The author is valid! Yes!');}
1
2
AppBundle\Author.name:
  This value should not be blank

Protected和private属性以及“getter”方法也可以被验证(见 约束的投放范围)。

使用验证服务 

接下来,要真正的校验 Author 对象,使用 validator 服务(Validator 类)的 validate 方法。 validator 的工作很简单:读取一个类的约束规则来校验对象数据是否满足这些约束。如果验证失败,一个非空的错误列表(ConstraintViolationList类)将被返回。在控制器中实践这个简单例子:

if (count($errors) > 0) {
    return $this->render('author/validation.html.twig', array(
        'errors' => $errors,
    ));}

如果 $nameLes propriétés protégées et privées et les méthodes "getter" peuvent également être vérifié (voir < a href="#catalog16">Plage de livraison contrainte
).

Si vous insérez une valeur pour l'attribut name, un délicieux message de réussite apparaîtra. name 属性插入一个值,令人高兴的成功信息就会出现。

你也可以传递“错误信息集合”(collection of errors)到模版中:

XML:<!-- app/config/config.xml --><?xml version="1.0" encoding="UTF-8" ?><container xmlns="http://symfony.com/schema/dic/services"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:framework="http://symfony.com/schema/dic/symfony"    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd        http://symfony.com/schema/dic/symfony http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">     <framework:config>
       <framework:validation enable-annotations="true" />    </framework:config></container>

在模版中,你可以根据需要精确输出错误列表:

YAML:# app/config/config.ymlframework:
    validation: { enable_annotations: true }
PHP:// src/AppBundle/Entity/Author.php // ...use Symfony\Component\Validator\Mapping\ClassMetadata;use Symfony\Component\Validator\Constraints as Assert; class Author{
    public $gender;     // ...     public static function loadValidatorMetadata(ClassMetadata $metadata)
    {
        // ...         $metadata->addPropertyConstraint('gender', new Assert\Choice(array(
            'choices' => array('male', 'female', 'other'),
            'message' => 'Choose a valid gender.',
        )));
    }}


每一个验证错误(被称为“constraint violation/约束违反”)都由一个 ConstraintViolation

La plupart du temps, vous n'avez pas besoin de contacter le validateur directement interactif, ou ne vous inquiétez pas de la sortie de messages d'erreur. Dans la plupart des cas, vous utilisez la validation indirectement lors du traitement des données du formulaire soumis. Voir Validation et formulaires
pour en savoir plus.

Vous pouvez également transmettre une "collection d'erreurs" au modèle :

XML:<!-- 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\Author">
        <property name="gender">
            <constraint name="Choice">
                <option name="choices">
                    <value>male</value>
                    <value>female</value>
                    <value>other</value>
                </option>
                <option name="message">Choose a valid gender.</option>
            </constraint>
        </property>         <!-- ... -->
    </class></constraint-mapping>

Dans le modèle, vous pouvez Besoin de sortir l'erreur lister avec précision :

YAML:# src/AppBundle/Resources/config/validation.ymlAppBundle\Entity\Author:
    properties:
        gender:
            - Choice: { choices: [male, female, other], message: Choose a valid gender. }
        # ...

Annotations:// src/AppBundle/Entity/Author.php // ...use Symfony\Component\Validator\Constraints as Assert; class Author{
    /**
     * @Assert\Choice(
     *     choices = { "male", "female", "other" },
     *     message = "Choose a valid gender."
     * )
     */
    public $gender;     // ...}

#🎜🎜#
#🎜🎜#Chaque erreur de validation (appelée "violation de contrainte/violation de contrainte") est représentée par un ConstraintViolation#🎜🎜# objet à restituer. #🎜🎜##🎜🎜##🎜🎜##🎜🎜#Configuration #🎜🎜#¶#🎜🎜##🎜🎜##🎜🎜#Le validateur de Symfony est activé par défaut, mais si vous utilisez une annotation pour spécifier des contraintes, l'annotation (pour vérification) doit être explicitement activée : #🎜🎜#
PHP:// src/AppBundle/Entity/Author.php // ...use Symfony\Component\Validator\Mapping\ClassMetadata;use Symfony\Component\Validator\Constraints as Assert; class Author{
    protected $gender;     public static function loadValidatorMetadata(ClassMetadata $metadata)
    {
        // ...         $metadata->addPropertyConstraint(
            'gender',
            new Assert\Choice(array('male', 'female', 'other'))
        );
    }}
#🎜🎜#
XML:<!-- 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\Author">
        <property name="gender">
            <constraint name="Choice">
                <value>male</value>
                <value>female</value>
                <value>other</value>
            </constraint>
        </property>         <!-- ... -->
    </class></constraint-mapping>
YAML:# src/AppBundle/Resources/config/validation.ymlAppBundle\Entity\Author:
    properties:
        gender:
            - Choice: [male, female, other]
        # ...
#🎜🎜##🎜🎜##🎜🎜##🎜🎜#

Règles de contrainte

Validator 被设计成针对 约束(即规则)来验证对象。要验证一个对象,只需把一或多个约束映射到它要验证的类,然后再把它传递给 validator Il suffit de servir.

En coulisses, une contrainte est un objet PHP qui génère une instruction pour la prise de décision. En pratique, une contrainte pourrait être « le gâteau ne doit pas brûler ». Dans Symfony, les contraintes sont similaires : ce sont des assertions indiquant si une condition est vraie. Étant donné une valeur, la contrainte vous indique si la valeur obéit à vos règles de contrainte.

Contraintes prises en charge

Symfony encapsule bon nombre des contraintes les plus couramment utilisées :

Contraintes de base #🎜🎜 #¶

Ce sont des contraintes de base : utilisez-les pour affirmer des choses très basiques sur les valeurs de propriété, ou pour affirmer les valeurs de retour des méthodes dans votre programme.

Pas identique à erThanOrEqual

Date

Contraintes de collection Compte

Contraintes financières financières

Currency

  • Luhn
  • Iban
  • Isbn
  • Issn
  • Autres Contraintes
  • Valide
  • Vous pouvez également créer votre propre Définir contraintes. L'article
  • Comment créer des contraintes de validation personnalisées couvre ce sujet.

    Configuration des contraintes

    Certaines contraintes, comme NotBlank sont plus simples, tandis que d'autres, comme les contraintes Choice, ont de nombreuses options de configuration disponibles. Supposons que la classe Auteur possède un autre attribut appelé genre, qui peut être défini sur "masculin", "femelle" ou "autre" : Author 类有另外一个属性叫 gender,该属性可以被设置为“male”、“female” 或 “other”:

    Annotations:// src/AppBundle/Entity/Author.php // ...use Symfony\Component\Validator\Constraints as Assert; class Author{
        /**
         * @Assert\Choice({"male", "female", "other"})
         */
        protected $gender;     // ...}
    PHP:// src/AppBundle/Entity/Author.php // ...use Symfony\Component\Validator\Mapping\ClassMetadata;use Symfony\Component\Validator\Constraints as Assert; class Author{
        private $firstName;     public static function loadValidatorMetadata(ClassMetadata $metadata)
        {
            $metadata->addPropertyConstraint('firstName', new Assert\NotBlank());
            $metadata->addPropertyConstraint(
                'firstName',
                new Assert\Length(array("min" => 3))
            );
        }}
    XML:<!-- 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\Author">
            <property name="firstName">
                <constraint name="NotBlank" />
                <constraint name="Length">
                    <option name="min">3</option>
                </constraint>
            </property>
        </class></constraint-mapping>
    YAML:# src/AppBundle/Resources/config/validation.ymlAppBundle\Entity\Author:
        properties:
            firstName:
                - NotBlank: ~
                - Length:
                    min: 3

    约束的选项始终可以通过一个数组来传递的。有些约束也允许你传入一个 ”default” 选项的值来代替这个数组。在 Choice 约束中,choices 选项就可以通过这种方式指定。

    Annotations:// src/AppBundle/Entity/Author.php // ...use Symfony\Component\Validator\Constraints as Assert; class Author{
        /**
         * @Assert\NotBlank()
         * @Assert\Length(min=3)
         */
        private $firstName;}
    PHP:// src/AppBundle/Entity/Author.php // ...use Symfony\Component\Validator\Mapping\ClassMetadata;use Symfony\Component\Validator\Constraints as Assert; class Author{
        public static function loadValidatorMetadata(ClassMetadata $metadata)
        {
            $metadata->addGetterConstraint('passwordLegal', new Assert\IsTrue(array(
                'message' => 'The password cannot match your first name',
            )));
        }}
    XML:<!-- 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\Author">
            <getter property="passwordLegal">
                <constraint name="IsTrue">
                    <option name="message">The password cannot match your first name</option>
                </constraint>
            </getter>
        </class></constraint-mapping>
    YAML:# src/AppBundle/Resources/config/validation.ymlAppBundle\Entity\Author:
        getters:
            passwordLegal:
                - 'IsTrue': { message: 'The password cannot match your first name' }

    这纯粹是为了让最常见的配置选项在用起来时更加的简单快速。

    如果你不确定如何指定一个选项,要么去查看API文档,要么为了保险起见,通过一个选项数组来传入(即上面第一种方式)。

    约束的目标 

    约束可以被应用到类的属性(如 name)或者一个公共的getter方法(如 getFullName)乃至整个类上。属性约束最常用也最简单,而Getter约束则允许你指定更加复杂的验证规则。最后,如果,类约束的使用场景是,你要将类作为整体进行验证。

    属性约束 

    类属性的验证是一个最基本的验证技巧。Symfony允许你校验 private, protected 或者 public 属性。下面代码展示了如何配置 Author 对象的 $firstName

    Annotations:// src/AppBundle/Entity/Author.php // ...use Symfony\Component\Validator\Constraints as Assert; class Author{
        /**
         * @Assert\IsTrue(message = "The password cannot match your first name")
         */
        public function isPasswordLegal()
        {
            // ... return true or false
        }}
    public function isPasswordLegal(){
        return $this->firstName !== $this->password;}
    rrreee

    rrreee
    Options contraintes peut toujours être transmis via un tableau. Certaines contraintes permettent également de passer une valeur pour l'option "default" à la place de ce tableau. Dans une contrainte Choice, l'option choices peut être spécifiée de cette manière. 🎜rrreeerrreeerrreee🎜rrreee🎜🎜Cela vise uniquement à rendre les options de configuration les plus courantes plus faciles et plus rapides à utiliser. 🎜🎜Si vous ne savez pas comment spécifier une option, consultez la documentation de l'API ou, par mesure de sécurité, transmettez-la via un tableau d'options (c'est-à-dire la première méthode ci-dessus). 🎜

    Objectifs des contraintes ¶🎜

    🎜Les contraintes peuvent être appliquées aux attributs de classe (tels que nom) ou une méthode getter publique (telle que getFullName) ou même la classe entière. Les contraintes d'attribut sont les plus couramment utilisées et les plus simples, tandis que les contraintes Getter vous permettent de spécifier des règles de validation plus complexes. Enfin, si le cas d'utilisation des contraintes de classe est que vous souhaitez vérifier la classe dans son ensemble. 🎜🎜Contraintes d'attribut ¶🎜🎜🎜La vérification des attributs de classe est l'une des techniques de vérification les plus élémentaires. Symfony vous permet de vérifier des propriétés privées, protégées ou publiques. Le code suivant montre comment configurer la propriété $firstName de l'objet Author pour qu'il comporte au moins 3 caractères : 🎜rrreeerrreeerrreee🎜rrreee🎜

    Contraintes Getters

    Les contraintes peuvent également être appliquées à la valeur de retour d'une méthode. Symfony vous permet d'ajouter une contrainte à toute méthode publique commençant par "get", "is" ou "has". Ce type de méthode est appelé « getters ».

    L'avantage de cette technique est qu'elle vous permet de valider dynamiquement vos objets. Par exemple, supposons que vous souhaitiez vous assurer que le champ du mot de passe ne correspond pas au prénom de l'utilisateur (pour des raisons de sécurité). Vous pouvez le faire en créant une méthode isPasswordLegal, puis en affirmant que la méthode doit renvoyer true : isPasswordLegal 方法,然后断言该方法必须返回 true 来实现:

    rrreeerrreeerrreeerrreee

    现在,创建一个 isPasswordLegal() 方法,含有你所需的逻辑:

    rrreee


    眼尖的人可能会注意到,在YAML, XML和PHP的约束配置格式中,getter的前缀(“get”、”is” 或者 “has”) 在映射时被忽略了。这能让你在不改变验证逻辑的前提下,把一个约束移动到后面的一个同名属性之上(反之亦然)。


    类约束 

    有一些约束可以应用到被验证的整个类。例如,Callback 类型的约束,就是一个可以作用到类本身的通用约束。当类被验证时,约束所指定的方法将被直接执行,以便提供更多的自定义验证。

    总结 

    Symfony的 validatorrrreeerrreeerrreeerrreee

    Maintenant, créez un isPasswordLegal() méthode , contenant la logique dont vous avez besoin :
    rrreee

    Les plus attentifs remarqueront peut-être que les formats de configuration de contraintes sont disponibles en YAML, XML et PHP , le préfixe getter ("get", "is" ou "has") est ignoré lors du mappage. Cela vous permet de déplacer une contrainte vers une propriété ultérieure du même nom (et vice versa) sans modifier la logique de validation.

🎜🎜Contraintes de classe ¶🎜🎜🎜Certaines contraintes peuvent être appliquées à l'ensemble de la classe en cours de vérification. Par exemple, la contrainte de type Callback🎜 est une contrainte générale qui peut être appliquée à la classe elle-même. Lorsqu'une classe est validée, les méthodes spécifiées par les contraintes seront exécutées directement pour fournir une validation plus personnalisée. 🎜🎜Résumé ¶🎜🎜🎜Le validateur (validation) de Symfony est un outil puissant qui peut être utilisé pour garantir la légalité des données de n’importe quel objet. Sa puissance vient des contraintes, que vous pouvez appliquer aux propriétés des objets et aux méthodes getter. Bien que, dans la plupart des cas, le cadre de validation soit appliqué indirectement lors de l’utilisation de formulaires, rappelez-vous qu’il peut être utilisé n’importe où pour valider n’importe quel objet. 🎜🎜🎜🎜🎜🎜🎜🎜