The Expression Syntax
The ExpressionLanguage component uses a specific syntax which is based on the expression syntax of Twig. In this document, you can find all supported syntaxes.
Supported Literals
The component supports:
- strings - single and double quotes (e.g.
'hello'
) - numbers - integers (e.g.
103
), decimals (e.g.9.95
), decimals without leading zeros (e.g..99
, equivalent to0.99
); all numbers support optional underscores as separators to improve readability (e.g.1_000_000
,3.14159_26535
) - arrays - using JSON-like notation (e.g.
[1, 2]
) - hashes - using JSON-like notation (e.g.
{ foo: 'bar' }
) - booleans -
true
andfalse
- null -
null
- exponential - also known as scientific (e.g.
1.99E+3
or1e-2
)
6.1
Support for decimals without leading zeros and underscore separators were introduced in Symfony 6.1.
Caution
A backslash (\
) must be escaped by 3 backslashes (
) in a string
and 7 backslashes (
) in a regex:
1 2
echo $expressionLanguage->evaluate('"\\\\"'); // prints \
$expressionLanguage->evaluate('"a\\\\b" matches "/^a\\\\\\\\b$/"'); // returns true
Control characters (e.g. \n
) in expressions are replaced with
whitespace. To avoid this, escape the sequence with a single backslash
(e.g. \\n
).
Working with Objects
When passing objects into an expression, you can use different syntaxes to access properties and call methods on the object.
Accessing Public Properties
Public properties on objects can be accessed by using the .
syntax, similar
to 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,
]
));
This will print out Honeycrisp
.
Calling Methods
The .
syntax can also be used to call methods on an object, similar to
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,
]
));
This will print out Hi Hi Hi!
.
Null-safe Operator
Use the ?.
syntax to access properties and methods of objects that can be
null
(this is equivalent to the $object?->propertyOrMethod
PHP null-safe
operator):
1 2 3 4 5 6 7
// these will throw an exception when `fruit` is `null`
$expressionLanguage->evaluate('fruit.color', ['fruit' => '...'])
$expressionLanguage->evaluate('fruit.getStock()', ['fruit' => '...'])
// these will return `null` if `fruit` is `null`
$expressionLanguage->evaluate('fruit?.color', ['fruit' => '...'])
$expressionLanguage->evaluate('fruit?.getStock()', ['fruit' => '...'])
6.1
The null safe operator was introduced in Symfony 6.1.
Null-Coalescing Operator
It returns the left-hand side if it exists and it's not null
; otherwise it
returns the right-hand side. Expressions can chain multiple coalescing operators:
foo ?? 'no'
foo.baz ?? 'no'
foo[3] ?? 'no'
foo.baz ?? foo['baz'] ?? 'no'
Note
The main difference with the null-coalescing operator in PHP is that ExpressionLanguage will throw an exception when trying to access a non-existent variable.
6.2
The null-coalescing operator was introduced in Symfony 6.2.
Working with Functions
You can also use registered functions in the expression by using the same syntax as PHP and JavaScript. The ExpressionLanguage component comes with the following functions by default:
constant()
enum()
constant()
function
This function will return the value of a PHP constant:
1 2 3 4 5
define('DB_USER', 'root');
var_dump($expressionLanguage->evaluate(
'constant("DB_USER")'
));
This will print out root
.
This also works with class constants:
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")'
));
This will print out /api
.
enum()
function
This function will return the case of an enumeration:
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")'
));
This will print out true
.
6.3
The enum()
function was introduced in Symfony 6.3.
Tip
To read how to register your own functions to use in an expression, see "The ExpressionLanguage Component".
Working with Arrays
If you pass an array into an expression, use the []
syntax to access
array keys, similar to 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,
]
));
This will print out 42
.
Supported Operators
The component comes with a lot of operators:
Arithmetic Operators
+
(addition)-
(subtraction)*
(multiplication)/
(division)%
(modulus)**
(pow)
For example:
1 2 3 4 5 6 7 8
var_dump($expressionLanguage->evaluate(
'life + universe + everything',
[
'life' => 10,
'universe' => 10,
'everything' => 22,
]
));
This will print out 42
.
Bitwise Operators
&
(and)|
(or)^
(xor)
Comparison Operators
==
(equal)===
(identical)!=
(not equal)!==
(not identical)<
(less than)>
(greater than)<=
(less than or equal to)>=
(greater than or equal to)matches
(regex match)contains
starts with
ends with
6.1
The contains
, starts with
and ends with
operators were introduced
in Symfony 6.1.
Tip
To test if a string does not match a regex, use the logical not
operator in combination with the matches
operator:
1
$expressionLanguage->evaluate('not ("foo" matches "/bar/")'); // returns true
You must use parentheses because the unary operator not
has precedence
over the binary operator matches
.
Examples:
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,
]
);
Both variables would be set to false
.
Logical Operators
not
or!
and
or&&
or
or||
For example:
1 2 3 4 5 6 7 8
$ret = $expressionLanguage->evaluate(
'life < universe or life < everything',
[
'life' => 10,
'universe' => 10,
'everything' => 22,
]
);
This $ret
variable will be set to true
.
String Operators
~
(concatenation)
For example:
1 2 3 4 5 6 7
var_dump($expressionLanguage->evaluate(
'firstName~" "~lastName',
[
'firstName' => 'Arthur',
'lastName' => 'Dent',
]
));
This would print out Arthur Dent
.
Array Operators
in
(contain)not in
(does not contain)
For example:
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,
]
);
The $inGroup
would evaluate to true
.
6.3
In Symfony versions previous to 6.3, in
and not in
operators
were using loose comparison. Using these operators with variables of
different types is now deprecated, and these operators will be using
strict comparison from Symfony 7.0.
Numeric Operators
..
(range)
For example:
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,
]
);
This will evaluate to true
, because user.age
is in the range from
18
to 45
.
Ternary Operators
foo ? 'yes' : 'no'
foo ?: 'no'
(equal tofoo ? foo : 'no'
)foo ? 'yes'
(equal tofoo ? 'yes' : ''
)
Operators Precedence
Operator precedence determines the order in which operations are processed in an
expression. For example, the result of the expression 1 + 2 * 4
is 9
and not 12
because the multiplication operator (*
) takes precedence over
the addition operator (+
).
To avoid ambiguities (or to alter the default order of operations) add
parentheses in your expressions (e.g. (1 + 2) * 4
or 1 + (2 * 4)
.
The following table summarizes the operators and their associativity from the highest to the lowest precedence:
Operators | Associativity |
---|---|
- , + (unary operators that add the number sign) |
none |
** |
right |
* , / , % |
left |
not , ! |
none |
~ |
left |
+ , - |
left |
.. |
left |
== , === , != , !== ,
< , > , >= , <= ,
not in , in , contains ,
starts with , ends with , matches |
left |
& |
left |
^ |
left |
| |
left |
and , && |
left |
or , || |
left |
Built-in Objects and Variables
When using this component inside a Symfony application, certain objects and variables are automatically injected by Symfony so you can use them in your expressions (e.g. the request, the current user, etc.):