Синтаксис выражений

Дата обновления перевода 2024-07-25

Синтаксис выражений

Компонент ExpressionLanguage использует специфический синтаксис, который базируется на синтаксисе выражений Twig. В этом документе вы можете найти все поддерживаемые синтаксисы.

Поддерживаемые литералы

Компонент поддерживает:

  • строки - одинарные и двойные кавычки (например, 'hello')
  • числа - целые числа (например, 103), десятичные (например, 9.95), десятичные дроби без начальных нулей (например, .99, эквивалентно 0.99); все числа поддерживают необязательные подчёркивания как разделители для улучшения читабельности (например, 1_000_000, 3.14159_26535)
  • массивы - с использованием JSON-подобной нотации (например, [1, 2])
  • хеши - с использованием JSON-подобной нотации (например, { foo: 'bar' })
  • булевые числа - true и false
  • null - нуль
  • экспоненциальные числа - также известные как научные (например, 1.99E+3 или 1e-2)

Caution

Обратный слеш (\) должен быть экранирован 4 обратными слешами (\\\\) в строке и 8 обратными слешами (\\\\\\\\) в регулярном выражении:

1
2
echo $expressionLanguage->evaluate('"\\\\"'); // виводить \
$expressionLanguage->evaluate('"a\\\\b" відповідає "/^a\\\\\\\\b$/"'); // повертає true

Контрольные символы (например, \n) в выражениях заменяются пробелами. Чтобы избежать этого, экранируйте последовательность одним обратным слешем (например, \\n).

Работа с объектами

При передаче объектов в выражение можно использовать различные синтаксисы для доступа к свойствам и вызова методов объекта.

Доступ к публичным свойствам

Доступ к публичным свойствам объектов можно получить с помощью синтаксиса ., подобно JavaScript:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Apple
{
    public string $variety;
}

$apple = new Apple();
$apple->variety = 'Honeycrisp';

var_dump($expressionLanguage->evaluate(
    'fruit.variety',
    [
        'fruit' => $apple,
    ]
));

Это выведет Honeycrisp.

Вызов методов

Синтаксис . также можно использовать для вызова методов в объекте, подобно JavaScript:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Robot
{
    public function sayHi(int $times): string
    {
        $greetings = [];
        for ($i = 0; $i < $times; $i++) {
            $greetings[] = 'Hi';
        }

        return implode(' ', $greetings).'!';
    }
}

$robot = new Robot();

var_dump($expressionLanguage->evaluate(
    'robot.sayHi(3)',
    [
        'robot' => $robot,
    ]
));

Это выведет Hi Hi Hi!.

Оператор защиты от null

Используйте синтаксис ?. для доступа к свойствам и методам объектов, которые могут быть null (это эквивалентно PHP оператору защиты от null $object?->propertyOrMethod):

1
2
3
4
5
6
7
// это сгенерирует исключение, если `fruit` - `null`.
$expressionLanguage->evaluate('fruit.color', ['fruit' => '...'])
$expressionLanguage->evaluate('fruit.getStock()', ['fruit' => '...'])

// это вернёт `null`, если `fruit` - `null
$expressionLanguage->evaluate('fruit?.color', ['fruit' => '...'])
$expressionLanguage->evaluate('fruit?.getStock()', ['fruit' => '...'])

Оператор коалесценции нуля

Возвращает левую часть, если она существует и не является null; в противном случае
возвращает правую часть. Выражения могут объединять несколько операторов коалесценции:

  • foo ?? 'no'
  • foo.baz ?? 'no'
  • foo[3] ?? 'no'
  • foo.baz ?? foo['baz'] ?? 'no'

Note

Основное отличие от оператора нулевой коалесценции в PHP заключается в том, что
ExpressionLanguage будет вызывать исключение при попытке доступа к несуществующей переменной.

Работа с функциями

Вы также можете использовать зарегистрированные функции в выражении, используя тот же синтаксис, что и в PHP и JavaScript. Компонент ExpressionLanguage поставляется со следующими функциями по умолчанию:

  • constant()
  • enum()
  • min()
  • max()

Функция constant()

Эта функция вернёт значение константы PHP:

1
2
3
4
5
define('DB_USER', 'root');

var_dump($expressionLanguage->evaluate(
    'constant("DB_USER")'
));

Это выведет root.

Это также работает с константами класса:

1
2
3
4
5
6
7
8
9
10
namespace App\SomeNamespace;

class Foo
{
    public const API_ENDPOINT = '/api';
}

var_dump($expressionLanguage->evaluate(
    'constant("App\\\SomeNamespace\\\Foo::API_ENDPOINT")'
));

Это выведет /api.

Функция enum()

Эта функция вернёт случай исчисления:

1
2
3
4
5
6
7
8
9
10
namespace App\SomeNamespace;

enum Foo
{
    case Bar;
}

var_dump(App\Enum\Foo::Bar === $expressionLanguage->evaluate(
    'enum("App\\\SomeNamespace\\\Foo::Bar")'
));

Это выведет true.

Функция min()

Эта функция вернет наименьшее значение из заданных параметров. Вы можете передавать различные типы параметров (например, даты, строки, числовые значения) и даже смешивать их (например, передавать числовые значения и строки). Внутренне функция использует PHP-функцию min для поиска наименьшего значения:

1
2
3
var_dump($expressionLanguage->evaluate(
    'min(1, 2, 3)'
));

Это выведет 1.

Функция max()

Эта функция вернет наибольшее значение из заданных параметров. Вы можете передавать различные типы параметров (например, даты, строки, числовые значения) и даже смешивать их (например, передавать числовые значения и строки). Внутренне функция использует
PHP-функцию max для поиска наибольшего значения:

1
2
3
var_dump($expressionLanguage->evaluate(
    'max(1, 2, 3)'
));

Это выведет 3.

7.1

Функции min() и max() были представлены в Symfony 7.1.

Tip

О том, как зарегистрировать собственные функции для использования в выражении, см. "".

Работа с массивами

Если вы передаёте массив в выражение, используйте синтаксис [] для доступа к к ключам массива, подобно JavaScript:

1
2
3
4
5
6
7
8
$data = ['life' => 10, 'universe' => 10, 'everything' => 22];

var_dump($expressionLanguage->evaluate(
    'data["life"] + data["universe"] + data["everything"]',
    [
        'data' => $data,
    ]
));

Это выведет 42.

Поддерживаемые операторы

Компонент поставляется со многими операторами:

Арифметические операторы

  • + (сложение)
  • - (вычитание)
  • * (умножение)
  • / (деление)
  • % (модуль)
  • ** (pow)

Например:

1
2
3
4
5
6
7
8
var_dump($expressionLanguage->evaluate(
    'life + universe + everything',
    [
        'life' => 10,
        'universe' => 10,
        'everything' => 22,
    ]
));

Это выведет 42.

Битовые операторы

  • & (и)
  • | (или)
  • ^ (xor)

Операторы сравнения

  • == (равно)
  • === (идентично)
  • != (не равно)
  • !== (не идентично)
  • < (меньше, чем)
  • >` (больше, чем)
  • <= (меньше или равно)
  • >= (больше или равно)
  • matches (совпадение с регулярным выражением)
  • contains
  • starts with
  • ends with

6.1

Операторы contains, starts with и ends with были представлены в Symfony 6.1.

Tip

Чтобы протестировать, что строка не соответствует регулярному выражению, используйте логический оператор not в сочетании с оператором matches:

1
$expressionLanguage->evaluate('not ("foo" matches "/bar/")'); // повертає true

Вы должны использовать круглые скобки, поскольку унарный оператор not имеет приоритет над бинарным оператором matches.

Примеры:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ret1 = $expressionLanguage->evaluate(
    'life == everything',
    [
        'life' => 10,
        'everything' => 22,
    ]
);

$ret2 = $expressionLanguage->evaluate(
    'life > everything',
    [
        'life' => 10,
        'everything' => 22,
    ]
);

Обе переменные будут установлены как false.

Логические операторы

  • not или !
  • and или &&
  • or или ||

Например:

1
2
3
4
5
6
7
8
$ret = $expressionLanguage->evaluate(
    'life < universe or life < everything',
    [
        'life' => 10,
        'universe' => 10,
        'everything' => 22,
    ]
);

Эта переменная $ret будет установлена как true.

Операторы строки

  • ~ (конкатенация)

Например:

1
2
3
4
5
6
7
var_dump($expressionLanguage->evaluate(
    'firstName~" "~lastName',
    [
        'firstName' => 'Arthur',
        'lastName' => 'Dent',
    ]
));

Это выведет Arthur Dent.

Операторы массива

  • in (содержит)
  • not in (не содержит)

Например:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class User
{
    public string $group;
}

$user = new User();
$user->group = 'human_resources';

$inGroup = $expressionLanguage->evaluate(
    'user.group in ["human_resources", "marketing"]',
    [
        'user' => $user,
    ]
);

$inGroup будет оцениваться как true.

Note

Операторы in и not in используют строгое сравнение.

Числовые операторы

  • .. (диапазон)

Например:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class User
{
    public int $age;
}

$user = new User();
$user->age = 34;

$expressionLanguage->evaluate(
    'user.age in 18..45',
    [
        'user' => $user,
    ]
);

Это будет оцениваться как true, потому что user.age находится в диапазоне от 18 до 45.

Тройные операторы

  • foo ? 'yes' : 'no'
  • foo ?: 'no' (равняется foo ? foo : 'no')
  • foo ? 'yes' (равняется foo ? 'yes' : '')

Другие операторы

  • ?. (оператор защиты от нуля )
  • ?? (оператор нулевой коалесценции )

Встроенные объекты и переменные

При использовании этого компонента в приложении Symfony определённые объекты и переменные автоматически внедряются Symfony, чтобы вы могли использовать их в своих выражениях (например, запрос, текущий пользователь и т.д.):