Expression ========== This constraint allows you to use an :ref:`expression ` for more complex, dynamic validation. See `Basic Usage`_ for an example. See :doc:`/reference/constraints/Callback` for a different constraint that gives you similar flexibility. ========== =================================================================== Applies to :ref:`class ` or :ref:`property/method ` Options - :ref:`expression ` - `groups`_ - `message`_ - `payload`_ - `values`_ Class :class:`Symfony\\Component\\Validator\\Constraints\\Expression` Validator :class:`Symfony\\Component\\Validator\\Constraints\\ExpressionValidator` ========== =================================================================== Basic Usage ----------- Imagine you have a class ``BlogPost`` with ``category`` and ``isTechnicalPost`` properties:: // 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; } // ... } To validate the object, you have some special requirements: A) If ``isTechnicalPost`` is true, then ``category`` must be either ``php`` or ``symfony``; B) If ``isTechnicalPost`` is false, then ``category`` can be anything. One way to accomplish this is with the Expression constraint: .. configuration-block:: .. code-block:: php-annotations // 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 { // ... } .. code-block:: yaml # 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!" .. code-block:: xml .. code-block:: php // 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->addConstraint(new Assert\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!', ])); } // ... } The :ref:`expression ` option is the expression that must return true in order for validation to pass. To learn more about the expression language syntax, see :doc:`/components/expression_language/syntax`. .. sidebar:: Mapping the Error to a Specific Field You can also attach the constraint to a specific property and still validate based on the values of the entire entity. This is handy if you want to attach the error to a specific field. In this context, ``value`` represents the value of ``isTechnicalPost``. .. configuration-block:: .. code-block:: php-annotations // 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="If this is a tech post, the category should be either php or symfony!" * ) */ private $isTechnicalPost; // ... } .. code-block:: yaml # config/validator/validation.yaml App\Model\BlogPost: properties: isTechnicalPost: - Expression: expression: "this.getCategory() in ['php', 'symfony'] or value == false" message: "If this is a tech post, the category should be either php or symfony!" .. code-block:: xml .. code-block:: php // 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([ 'expression' => 'this.getCategory() in ["php", "symfony"] or value == false', 'message' => 'If this is a tech post, the category should be either php or symfony!', ])); } // ... } For more information about the expression and what variables are available to you, see the :ref:`expression ` option details below. Options ------- .. _reference-constraint-expression-option: ``expression`` ~~~~~~~~~~~~~~ **type**: ``string`` [:ref:`default option `] The expression that will be evaluated. If the expression evaluates to a false value (using ``==``, not ``===``), validation will fail. To learn more about the expression language syntax, see :doc:`/components/expression_language/syntax`. Inside of the expression, you have access to up to 2 variables: Depending on how you use the constraint, you have access to 1 or 2 variables in your expression: * ``this``: The object being validated (e.g. an instance of BlogPost); * ``value``: The value of the property being validated (only available when the constraint is applied directly to a property); .. include:: /reference/constraints/_groups-option.rst.inc ``message`` ~~~~~~~~~~~ **type**: ``string`` **default**: ``This value is not valid.`` The default message supplied when the expression evaluates to false. You can use the following parameters in this message: =============== ============================================================== Parameter Description =============== ============================================================== ``{{ value }}`` The current (invalid) value =============== ============================================================== .. include:: /reference/constraints/_payload-option.rst.inc values ~~~~~~ **type**: ``array`` **default**: ``[]`` The values of the custom variables used in the expression. Values can be of any type (numeric, boolean, strings, null, etc.) .. configuration-block:: .. code-block:: php-annotations // src/Model/Analysis.php namespace App\Model; use Symfony\Component\Validator\Constraints as Assert; class Analysis { /** * @Assert\Expression( * "value + error_margin < threshold", * values = { "error_margin": 0.25, "threshold": 1.5 } * ) */ private $metric; // ... } .. code-block:: yaml # config/validator/validation.yaml App\Model\Analysis: properties: metric: - Expression: expression: "value + error_margin < threshold" values: { error_margin: 0.25, threshold: 1.5 } .. code-block:: xml .. code-block:: php // src/Model/Analysis.php namespace App\Model; use Symfony\Component\Validator\Constraints as Assert; use Symfony\Component\Validator\Mapping\ClassMetadata; class Analysis { public static function loadValidatorMetadata(ClassMetadata $metadata) { $metadata->addPropertyConstraint('metric', new Assert\Expression([ 'expression' => 'value + error_margin < threshold', 'values' => ['error_margin' => 0.25, 'threshold' => 1.5], ])); } // ... }