Expression

Это ограничение позволяет вам использовать выражение для более сложной и динамичной валидации. См. Базовое применение, чтобы увидеть пример. См. Callback, чтобы узнать о другом ограничении, которое даст вам схожую гибкость.

Применяется к
---------------------------------------------------------------------------------------------=--
Опции
Класс Expression
Валидатор ExpressionValidator

Базовое применение

Представьте, что у вас есть класс BlogPost со свойствами category и isTechnicalPost:

 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
// src/Model/BlogPost.php
namespace App\Model;

use Symfony\Component\Validator\Constraints as Assert;

class BlogPost
{
    private $category;

    private $isTechnicalPost;

    // ...

    public function getCategory()
    {
        return $this->category;
    }

    public function setIsTechnicalPost($isTechnicalPost)
    {
        $this->isTechnicalPost = $isTechnicalPost;
    }

    // ...
}

Чтобы валидировать объект, вам нужны особенные требования:

  1. Если isTechnicalPost - "true", тогда category должна быть либо php, либо symfony;
  2. Если isTechnicalPost - "false", тогда category может быть любой.

Вот один из способов достичь этого с ограничением Выражения:

  • Annotations
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    // src/Model/BlogPost.php
    namespace App\Model;
    
    use Symfony\Component\Validator\Constraints as Assert;
    
    /**
     * @Assert\Expression(
     *     "this.getCategory() in ['php', 'symfony'] or !this.isTechnicalPost()",
     *     message="If this is a tech post, the category should be either php or symfony!"
     * )
     */
    class BlogPost
    {
        // ...
    }
    
  • YAML
    1
    2
    3
    4
    5
    6
    # config/validator/validation.yaml
    App\Model\BlogPost:
        constraints:
            - Expression:
                expression: "this.getCategory() in ['php', 'symfony'] or !this.isTechnicalPost()"
                message: "If this is a tech post, the category should be either php or symfony!"
    
  • XML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    <!-- config/validator/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="App\Model\BlogPost">
            <constraint name="Expression">
                <option name="expression">
                    this.getCategory() in ['php', 'symfony'] or !this.isTechnicalPost()
                </option>
                <option name="message">
                    If this is a tech post, the category should be either php or symfony!
                </option>
            </constraint>
        </class>
    </constraint-mapping>
    
  • PHP
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    // src/Model/BlogPost.php
    namespace App\Model;
    
    use Symfony\Component\Validator\Mapping\ClassMetadata;
    use Symfony\Component\Validator\Constraints as Assert;
    
    class BlogPost
    {
        public static function loadValidatorMetadata(ClassMetadata $metadata)
        {
            $metadata->addConstraint(new Assert\Expression(array(
                'expression' => 'this.getCategory() in ["php", "symfony"] or !this.isTechnicalPost()',
                'message' => 'If this is a tech post, the category should be either php or symfony!',
            )));
        }
    
        // ...
    }
    

Опция выражения - это выражением, которое должно вернуть "true", чтобы валидация была успешной. Чтобы узнать больше о синтаксисе языка выражений, см. The Expression Syntax.

Вы также можете присоединить ограничение к конкретному свойству и всё равно валидировать на основании значений всей сущности. Это удобно, если вы хотите присоединить ошибку к конкретному полю. В этом контексте, value представляет значение isTechnicalPost.

  • Annotations
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    // src/Model/BlogPost.php
    namespace App\Model;
    
    use Symfony\Component\Validator\Constraints as Assert;
    
    class BlogPost
    {
        // ...
    
        /**
         * @Assert\Expression(
         *     "this.getCategory() in ['php', 'symfony'] or value == false",
         *     message="Если это технический пост, категория должна быть либо php, либо symfony!"
         * )
         */
        private $isTechnicalPost;
    
        // ...
    }
    
  • YAML
    1
    2
    3
    4
    5
    6
    7
    # config/validator/validation.yaml
    App\Model\BlogPost:
        properties:
            isTechnicalPost:
                - Expression:
                    expression: "this.getCategory() in ['php', 'symfony'] or value == false"
                    message: "Если это технический пост, категория должна быть либо php, либо symfony!"
    
  • XML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <!-- config/validator/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="App\Model\BlogPost">
            <property name="isTechnicalPost">
                <constraint name="Expression">
                    <option name="expression">
                        this.getCategory() in ['php', 'symfony'] or value == false
                    </option>
                    <option name="message">
                        Если это технический пост, категория должна быть либо php, либо symfony!
                    </option>
                </constraint>
            </property>
        </class>
    </constraint-mapping>
    
  • PHP
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    // src/Model/BlogPost.php
    namespace App\Model;
    
    use Symfony\Component\Validator\Constraints as Assert;
    use Symfony\Component\Validator\Mapping\ClassMetadata;
    
    class BlogPost
    {
        public static function loadValidatorMetadata(ClassMetadata $metadata)
        {
            $metadata->addPropertyConstraint('isTechnicalPost', new Assert\Expression(array(
                'expression' => 'this.getCategory() in ["php", "symfony"] or value == false',
                'message' => 'Если это технический пост, категория должна быть либо php, либо symfony!',
            )));
        }
    
        // ...
    }
    

Чтобы узнать больше о выражении и о том, какие переменные вам доступны, см. детали оцпии выражение ниже.

Доступные опции

expression

тип: string [опция по умолчанию]

Выражение, которое будет оценено. Если выражение оценивается, как "false" значение (используя ==, а не ===), то валидация будет неудачной.

Чтобы узнать больше о синтаксисе языка выражений, см. The Expression Syntax.

Внутри выражения у вас есть доступ к 2 переменным:

В зависимости от того, как вы используете ограничение, у вас есть доступ к 1 или 2 переменным в вашем выражении:

  • this: Валидируемый объект (например, экземпляр BlogPost);
  • value: Значение валидируемого свойства (доступно только тогда, когда ограничение применяется напрямую к свойству);

message

тип: string по умолчанию: Это значение не является валидным.

Сообщение по умолчаню, поставляемое, когда выражение оценивается, как "false".

payload

type: mixed default: null

This option can be used to attach arbitrary domain-specific data to a constraint. The configured payload is not used by the Validator component, but its processing is completely up to you.

For example, you may want to use several error levels to present failed constraints differently in the front-end depending on the severity of the error.

Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.