PHP switch 條件判斷
switch 用於根據一個變數的不同值執行不同的程式碼。當有多個條件需要檢查同一個變數時,switch 比多個 if...else if 更簡潔易讀。
基本語法
<?php
$day = 3;
switch ($day) {
case 1:
echo "星期一";
break;
case 2:
echo "星期二";
break;
case 3:
echo "星期三";
break;
case 4:
echo "星期四";
break;
case 5:
echo "星期五";
break;
case 6:
echo "星期六";
break;
case 7:
echo "星期日";
break;
default:
echo "無效的日期";
}
// 輸出:星期三
?>
break 語句
break 用於跳出 switch 區塊。如果沒有 break,程式會繼續執行下一個 case(稱為 fall-through):
<?php
$grade = "B";
switch ($grade) {
case "A":
echo "優秀";
break;
case "B":
echo "良好";
// 忘記 break,會繼續執行下一個 case
case "C":
echo "及格";
break;
default:
echo "不及格";
}
// 輸出:良好及格
?>
忘記加
break 是常見的錯誤,會導致意外的 fall-through 行為。default 語句
default 處理所有不符合 case 的情況,類似 if...else 中的 else:
<?php
$fruit = "grape";
switch ($fruit) {
case "apple":
echo "這是蘋果";
break;
case "banana":
echo "這是香蕉";
break;
default:
echo "這是其他水果";
}
// 輸出:這是其他水果
?>
default 可以放在任何位置,但通常放在最後:
<?php
switch ($value) {
default:
echo "預設值";
break;
case 1:
echo "一";
break;
case 2:
echo "二";
break;
}
?>
多個 case 共用程式碼
利用 fall-through 特性,多個 case 可以共用同一段程式碼:
<?php
$month = 2;
switch ($month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
echo "這個月有 31 天";
break;
case 4:
case 6:
case 9:
case 11:
echo "這個月有 30 天";
break;
case 2:
echo "這個月有 28 或 29 天";
break;
default:
echo "無效的月份";
}
// 輸出:這個月有 28 或 29 天
?>
字串比較
switch 可以用於字串比較:
<?php
$command = "start";
switch ($command) {
case "start":
echo "啟動系統";
break;
case "stop":
echo "停止系統";
break;
case "restart":
echo "重啟系統";
break;
case "status":
echo "顯示狀態";
break;
default:
echo "未知指令";
}
?>
switch 的比較方式
switch 使用鬆散比較(==),而非嚴格比較(===):
<?php
$value = "0";
switch ($value) {
case 0:
echo "數字零";
break;
case "0":
echo "字串零";
break;
}
// 輸出:數字零(因為 "0" == 0 是 true)
?>
switch 使用鬆散比較,可能導致意外的結果。如果需要嚴格比較,使用 if...else 或 PHP 8 的 match 表達式。替代語法
在 HTML 模板中使用替代語法:
<?php $userRole = "admin"; ?>
<?php switch ($userRole): ?>
<?php case "admin": ?>
<p>您是管理員</p>
<?php break; ?>
<?php case "editor": ?>
<p>您是編輯者</p>
<?php break; ?>
<?php default: ?>
<p>您是一般使用者</p>
<?php endswitch; ?>
match 表達式 (PHP 8.0+)
PHP 8.0 引入了 match 表達式,它是 switch 的現代化替代方案。match 具有以下關鍵優勢:
- 嚴格比較:使用
===進行比較,避免switch的==可能帶來的 Bug。 - 是個表達式:可以回傳值,直接賦值給變數。
- 更簡潔:不需要
break,不會發生 fall-through。
<?php
$status = 200;
$message = match ($status) {
200 => "成功",
404 => "找不到頁面",
500 => "伺服器錯誤",
default => "未知狀態",
};
?>
更詳細的用法與對照,請參考:PHP match 表達式
switch vs match 對照表
| 特性 | switch | match |
|---|---|---|
| 比較方式 | 鬆散 (==) | 嚴格 (===) |
| 回傳值 | 無 | 有 |
| break | 需要 | 不需要 |
| fall-through | 有 | 無 |
| PHP 版本 | 全部 | 8.0+ |
實際應用範例
HTTP 狀態碼處理
<?php
$statusCode = 404;
// 使用 switch
switch ($statusCode) {
case 200:
$message = "OK";
break;
case 301:
case 302:
$message = "重新導向";
break;
case 400:
$message = "錯誤的請求";
break;
case 401:
$message = "未授權";
break;
case 403:
$message = "禁止存取";
break;
case 404:
$message = "找不到頁面";
break;
case 500:
$message = "伺服器錯誤";
break;
default:
$message = "未知狀態";
}
// 使用 match (PHP 8+)
$message = match ($statusCode) {
200 => "OK",
301, 302 => "重新導向",
400 => "錯誤的請求",
401 => "未授權",
403 => "禁止存取",
404 => "找不到頁面",
500 => "伺服器錯誤",
default => "未知狀態",
};
echo $message; // 找不到頁面
?>
路由處理
<?php
$action = $_GET['action'] ?? 'index';
switch ($action) {
case 'index':
include 'views/home.php';
break;
case 'about':
include 'views/about.php';
break;
case 'contact':
include 'views/contact.php';
break;
case 'login':
include 'views/login.php';
break;
default:
http_response_code(404);
include 'views/404.php';
}
?>
計算器
<?php
function calculate($a, $operator, $b) {
return match ($operator) {
'+' => $a + $b,
'-' => $a - $b,
'*' => $a * $b,
'/' => $b !== 0 ? $a / $b : throw new DivisionByZeroError(),
'%' => $a % $b,
'**' => $a ** $b,
default => throw new InvalidArgumentException("未知的運算子:$operator"),
};
}
echo calculate(10, '+', 5); // 15
echo calculate(10, '*', 3); // 30
echo calculate(2, '**', 10); // 1024
?>