Cover of the book Symfony 5: The Fast Track

Symfony 5: The Fast Track is the best book to learn modern Symfony development, from zero to production. +300 pages in full color showing how to combine Symfony with Docker, APIs, queues & async tasks, Webpack, Single-Page Applications, etc.

Buy printed version

New in Symfony 5.1: ExpressionLanguage validator

Contributed by
Andrey Sevastianov
in #35849.

The ExpressionLanguage component provides an engine to compile and evaluate expressions. It's used by many companies to allow non-developers write business rules (e.g. evaluate the following expression to decide if your store offers a discount: 'user["isActive"] == true and product["price"] > 20').

In Symfony 5.1 we've improved the ExpressionLanguage component to allow validating the expressions without parsing or evaluating them. The ExpressionLanguage and Parser classes now include a lint() method to validate expressions:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
use Symfony\Component\ExpressionLanguage\Lexer;
use Symfony\Component\ExpressionLanguage\Parser;

$lexer = new Lexer();
$parser = new Parser([]);
$parser->lint($lexer->tokenize($expression), $allowedVariableNames);

$expression = 'foo["some_key"].callFunction(a ? b)';
$allowedVariableNames = ['foo', 'a', 'b'];
// Result: no error; expression is valid.

$expression = 'foo["some_key")';
$allowedVariableNames = ['foo'];
// Result: Unclosed "[" around position 3 for expression `foo["some_key")`.

$expression = '{key: foo key2: bar}';
$allowedVariableNames = ['foo', 'bar'];
// Result: A hash value must be followed by a comma
//         Unexpected token "name" of value "key2" ("punctuation" expected with value ",")
//         around position 11 for expression `{key: foo key2: bar}`.

In addition to using these lint() methods, you can also use the new ExpressionLanguageSyntax constraint to validate that the value stored in some property defines valid ExpressionLanguage syntax (you can optionally validate the expression variable names too):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
namespace App\Entity;

use Symfony\Component\Validator\Constraints as Assert;

class Order
{
    /**
     * @Assert\ExpressionLanguageSyntax()
     */
    protected $promotion;

    /**
     * @Assert\ExpressionLanguageSyntax(
     *     names = ['user', 'shipping_centers'],
     *     validateNames = true
     * )
     */
    protected $shippingOptions;
}

Comments

Nice one, thanks !
The validation I really was expecting for, this really helps having a cleaner code, many thanks!

Comments are closed.

To ensure that comments stay relevant, they are closed for old posts.