Компонент ExpressionLanguage предоставляет механизм для компиляции и оценки выражений. Он используется многими компаниями, чтобы позволить не разработчикам писать бизнес-правила (например, оценить следующее выражение, чтобы решить, предлагает ли ваш магазин скидку: 'user ["isActive"] == true and product ["price"]> 20'
).
В Symfony 5.1 улучшили компонент ExpressionLanguage
, чтобы позволить проверять выражения без их анализа или оценки. Классы ExpressionLanguage
и Parser
теперь включают метод lint()
для проверки выражений:
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}`.
Помимо использования этих методов lint()
, вы также можете использовать новое ограничение ExpressionLanguageSyntax
, чтобы проверить, что значение, сохраненное в каком-либо свойстве, определяет допустимый синтаксис ExpressionLanguage
(вы также можете дополнительно проверить имена переменных выражения):
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;
}