表达式语法
ExpressionLanguage 组件 使用了一种特定的语法,该语法基于 Twig 的表达式语法。在本文档中,您可以找到所有支持的语法。
支持的字面量
该组件支持
- 字符串 - 单引号和双引号 (例如
'hello') - 数字 - 整数 (例如
103),小数 (例如9.95),不带前导零的小数 (例如.99,等同于0.99);所有数字都支持可选的下划线作为分隔符,以提高可读性 (例如1_000_000,3.14159_26535) - 数组 - 使用类似 JSON 的表示法 (例如
[1, 2]) - 哈希 - 使用类似 JSON 的表示法 (例如
{ foo: 'bar' }) - 布尔值 -
true和false - null -
null - 指数 - 也称为科学计数法 (例如
1.99E+3或1e-2) - 注释 - 使用
/*和*/(例如/* this is a comment */)
7.2
Symfony 7.2 中引入了对表达式内注释的支持。
警告
反斜杠 (\) 在字符串中必须用 3 个反斜杠 () 转义,在正则表达式中必须用 7 个反斜杠 () 转义
1 2
echo $expressionLanguage->evaluate('"\\\\"'); // prints \
$expressionLanguage->evaluate('"a\\\\b" matches "/^a\\\\\\\\b$/"'); // returns 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 的对象的属性和方法 (这等效于 PHP 空值安全运算符 $object?->propertyOrMethod)
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' => '...'])
空值合并运算符
如果左侧存在且不为 null,则返回左侧;否则返回右侧。表达式可以链式使用多个合并运算符
foo ?? 'no'foo.baz ?? 'no'foo[3] ?? 'no'foo.baz ?? foo['baz'] ?? 'no'
7.2
从 Symfony 7.2 开始,尝试访问不存在的变量时不会抛出异常。这与 PHP 中的空值合并运算符 的行为相同。
使用函数
您还可以通过使用与 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() 函数
此函数将返回枚举的 case
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() 函数
此函数将返回给定参数的最小值。您可以传递不同类型的参数 (例如,日期、字符串、数值),甚至可以混合它们 (例如,传递数值和字符串)。它在内部使用 min PHP 函数来查找最小值
1 2 3
var_dump($expressionLanguage->evaluate(
'min(1, 2, 3)'
));
这将打印出 1。
max() 函数
此函数将返回给定参数的最大值。您可以传递不同类型的参数 (例如,日期、字符串、数值),甚至可以混合它们 (例如,传递数值和字符串)。它在内部使用 max PHP 函数来查找最大值
1 2 3
var_dump($expressionLanguage->evaluate(
'max(1, 2, 3)'
));
这将打印出 3。
7.1
min() 和 max() 函数是在 Symfony 7.1 中引入的。
提示
要了解如何注册您自己的函数以在表达式中使用,请参阅 "ExpressionLanguage 组件"。
使用数组
如果将数组传递到表达式中,请使用 [] 语法来访问数组键,类似于 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。
支持的运算符
该组件附带了许多运算符
算术运算符
+(加法)-(减法)*(乘法)/(除法)%(取模)**(幂)
例如
1 2 3 4 5 6 7 8
var_dump($expressionLanguage->evaluate(
'life + universe + everything',
[
'life' => 10,
'universe' => 10,
'everything' => 22,
]
));
这将打印出 42。
比较运算符
==(等于)===(全等)!=(不等于)!==(非全等)<(小于)>(大于)<=(小于等于)>=(大于等于)matches(正则表达式匹配)包含以...开头以...结尾
提示
要测试字符串是否不匹配正则表达式,请将逻辑 not 运算符与 matches 运算符结合使用
1
$expressionLanguage->evaluate('not ("foo" matches "/bar/")'); // returns 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或||xor
7.2
Symfony 7.2 中引入了对 xor 逻辑运算符的支持。
例如
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。
注意
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' : '')
运算符优先级
运算符优先级决定了表达式中运算的处理顺序。例如,表达式 1 + 2 * 4 的结果是 9 而不是 12,因为乘法运算符 (*) 的优先级高于加法运算符 (+)。
为了避免歧义 (或更改操作的默认顺序),请在表达式中添加括号 (例如 (1 + 2) * 4 或 1 + (2 * 4)。
下表总结了运算符及其结合性,从最高优先级到最低优先级
| 运算符 | 结合性 |
|---|---|
- , +, ~ (添加数字符号的一元运算符) |
无 |
** |
右 |
*, /, % |
左 |
not, ! |
无 |
~ |
左 |
+, - |
左 |
.., <<, >> |
左 |
==, ===, !=, !==, <, >, >=, <=, not in, in, contains, starts with, ends with, matches |
左 |
& |
左 |
^ |
左 |
| |
左 |
and, && |
左 |
xor |
左 |
or, || |
左 |
内置对象和变量
当在 Symfony 应用程序内部使用此组件时,Symfony 会自动注入某些对象和变量,因此您可以在表达式中使用它们 (例如,请求、当前用户等)。