跳到內容

表達式語法

編輯此頁

ExpressionLanguage 組件 使用特定的語法,此語法基於 Twig 的表達式語法。在這份文件中,您可以找到所有支援的語法。

支援的字面值

此組件支援:

  • 字串 - 單引號和雙引號 (例如 'hello')
  • 數字 - 整數 (例如 103)、小數 (例如 9.95)、不帶前導零的小數 (例如 .99,等同於 0.99);所有數字都支援可選的底線作為分隔符,以提高可讀性 (例如 1_000_0003.14159_26535)
  • 陣列 - 使用類似 JSON 的表示法 (例如 [1, 2])
  • 雜湊 - 使用類似 JSON 的表示法 (例如 { foo: 'bar' })
  • 布林值 - truefalse
  • null - null
  • 指數 - 也稱為科學記號 (例如 1.99E+31e-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

位元運算子

  • & (and)
  • | (or)
  • ^ (xor)
  • ~ (not)
  • << (左移)
  • >> (右移)

7.2

~<<>> 位元運算子的支援是在 Symfony 7.2 中引入的。

比較運算子

  • == (等於)
  • === (全等)
  • != (不等於)
  • !== (非全等)
  • < (小於)
  • > (大於)
  • <= (小於或等於)
  • >= (大於或等於)
  • 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

注意

innot 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.age1845 的範圍內。

三元運算子

  • foo ? 'yes' : 'no'
  • foo ?: 'no' (等於 foo ? foo : 'no')
  • foo ? 'yes' (等於 foo ? 'yes' : '')

運算子優先順序

運算子優先順序決定表達式中運算被處理的順序。例如,表達式 1 + 2 * 4 的結果是 9 而不是 12,因為乘法運算子 (*) 的優先順序高於加法運算子 (+)。

為了避免歧義 (或更改預設的運算順序),請在表達式中加入括號 (例如 (1 + 2) * 41 + (2 * 4))。

下表總結了運算子及其關聯性,從最高到最低優先順序

運算子 關聯性
-+~ (新增數字符號的一元運算子)
**
*, /, %
not!
~
+, -
.., <<, >>
=====!=!==<>>=<=not inincontainsstarts withends withmatches
&
^
|
and&&
xor
or||

內建物件與變數

當在 Symfony 應用程式內部使用此組件時,Symfony 會自動注入某些物件和變數,因此您可以在表達式中使用它們 (例如請求、目前使用者等)。

本作品,包含程式碼範例,以 Creative Commons BY-SA 3.0 授權條款授權。
目錄
    版本