PHP match 表達式 (Match Expression)

match 是 PHP 8.0 引入的一種全新的條件控制結構。它類似於 switch,但語法更簡潔、功能更強大,且設計上更符合現代程式設計的需求。

基本語法

match 表達式會比較一個值與多個條件,並回傳第一個匹配分支的結果。

<?php
$status = 200;

$message = match ($status) {
    200 => "成功",
    404 => "找不到頁面",
    500 => "伺服器錯誤",
    default => "未知狀態",
};

echo $message; // 輸出:成功
?>

match 的關鍵特性

1. 它是表達式 (Expression)

switch 語句不同,match 是一個表達式。這意味著它會直接回傳一個值,你可以將結果賦值給變數,或者直接用於輸出。

2. 使用嚴格比較 (===)

match 使用嚴格比較 (===),這意味著它會同時檢查值的內容型別。這避免了 switch (使用 ==) 可能產生的非預期自動轉換問題。

<?php
$value = "0";

$result = match ($value) {
    0 => "這是數字零",
    "0" => "這是字串零",
};

echo $result; // 輸出:這是字串零
?>

3. 不需要 break

match 一旦找到匹配的分支,就會立即執行並回傳結果,不會像 switch 那樣產生 "fall-through"(自動執行下一個 case),因此完全不需要 break 關鍵字。

4. 必須窮舉所有情況 (Exhaustive)

match 要求必須處理所有可能的情況。如果沒有任何分支匹配,且沒有定義 default 分支,PHP 會拋出 UnhandledMatchError 例外。

<?php
$value = 5;

try {
    $result = match ($value) {
        1 => "一",
        2 => "二",
    };
} catch (UnhandledMatchError $e) {
    echo "錯誤:未處理的匹配狀況";
}
?>

進階用法

多個值共用同一分支

你可以用逗號分隔多個匹配條件。

<?php
$month = 2;

$days = match ($month) {
    1, 3, 5, 7, 8, 10, 12 => 31,
    4, 6, 9, 11 => 30,
    2 => 28,
    default => "未知月份",
};
?>

在匹配條件中使用表達式

匹配條件本身也可以是表達式。這讓 match 可以實作更複雜的邏輯,例如範圍判斷。

<?php
$score = 85;

$grade = match (true) {
    $score >= 90 => 'A',
    $score >= 80 => 'B',
    $score >= 70 => 'C',
    $score >= 60 => 'D',
    default => 'F',
};

echo $grade; // 輸出:B
?>
當使用 match (true) 時,它會回傳第一個條件表達式結果為 true 的分支。

在分支中執行函數或拋出例外

match 的分支不僅可以回傳值,也可以執行函數呼叫或拋出例外。

<?php
$status = 'error';

match ($status) {
    'ok' => handleSuccess(),
    'error' => throw new Exception("發生錯誤!"),
    default => null,
};
?>

switch vs match 對照表

特性switchmatch
比較方式鬆散比較 (==)嚴格比較 (===)
傳回值無 (語句)有 (表達式)
break必須使用,否則會 fall-through不需使用,不會 fall-through
多個條件共用使用多個 case 堆疊使用逗號分隔
預設處理default 是可選的必須有 default 或窮舉所有可能
PHP 版本PHP 4+PHP 8.0+

什麼時候該選用 match?

  • 當你需要將條件判斷的結果賦值給變數時。
  • 當你希望進行嚴格型別檢查以確保安全時。
  • 當分支邏輯相對單純(僅回傳值或簡單呼叫)時。
  • 為了避免忘記寫 break 造成的 Bug。

如果你的每個分支都需要執行多行複雜的邏輯(例如多個運算步驟),使用傳統的 if...elseswitch 語句可能在排版上會更清晰。