表達式語法
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 個反斜線 (
) 逸出,而在 regex 中則以 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 安全運算子
使用 ?.
語法來存取可能為 null
的物件的屬性和方法 (這等同於 PHP null 安全運算子 $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 聯合運算子
如果左側存在且不是 null
,則返回左側;否則返回右側。表達式可以鏈接多個聯合運算子
foo ?? 'no'
foo.baz ?? 'no'
foo[3] ?? 'no'
foo.baz ?? foo['baz'] ?? 'no'
7.2
從 Symfony 7.2 開始,當嘗試存取不存在的變數時,不會拋出例外。這與 PHP 中的 null 聯合運算子 的行為相同。
函式操作
您也可以在表達式中使用已註冊的函式,語法與 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
(regex 匹配)contains (包含)
starts with (開頭為)
ends with (結尾為)
提示
若要測試字串是否不匹配 regex,請將邏輯 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
對 xor
邏輯運算子的支援是在 Symfony 7.2 中引入的。
例如:
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' : ''
)
其他運算子
?.
(null 安全運算子)??
(null 聯合運算子)
運算子優先順序
運算子優先順序決定表達式中運算被處理的順序。例如,表達式 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 會自動注入某些物件和變數,因此您可以在表達式中使用它們 (例如請求、目前使用者等)。