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 對照表
| 特性 | switch | match |
|---|---|---|
| 比較方式 | 鬆散比較 (==) | 嚴格比較 (===) |
| 傳回值 | 無 (語句) | 有 (表達式) |
| break | 必須使用,否則會 fall-through | 不需使用,不會 fall-through |
| 多個條件共用 | 使用多個 case 堆疊 | 使用逗號分隔 |
| 預設處理 | default 是可選的 | 必須有 default 或窮舉所有可能 |
| PHP 版本 | PHP 4+ | PHP 8.0+ |
什麼時候該選用 match?
- 當你需要將條件判斷的結果賦值給變數時。
- 當你希望進行嚴格型別檢查以確保安全時。
- 當分支邏輯相對單純(僅回傳值或簡單呼叫)時。
- 為了避免忘記寫
break造成的 Bug。
如果你的每個分支都需要執行多行複雜的邏輯(例如多個運算步驟),使用傳統的 if...else 或 switch 語句可能在排版上會更清晰。