switch 是 PHP 多條件分支的常用結構,但其底層採用鬆散比較(==)而非嚴格比較(===),這導致著名的 '' == 0 為 true 的陷阱。本文詳細講解語法、陷阱、避坑方案與效能對比。
switch (表達式) {
case 值1:
// 代碼
break;
case 值2:
// 代碼
break;
default:
// 都不匹配時執行
}
<?php
var_dump('' == 0); // true —— 陷阱根源
var_dump('' === 0); // false
switch 內部等同於 if ($expr == $case),而非 ===。
$errId = ''; // 來自外部輸入,可能為空字符串
switch ($errId) {
case 0:
echo 'xxx'; // 會進入這裡!因為 '' == 0 為 true
break;
default:
echo 'yyy';
}
// 輸出:xxx —— 邏輯錯誤
$errId = $_GET['err_id'] ?? '';
if (!is_numeric($errId)) {
// 非數字直接返回/拋異常
die('無效錯誤碼');
}
switch ((int)$errId) { // 強制轉型
case 0: echo '錯誤碼 0'; break;
case 1: echo '錯誤碼 1'; break;
default: echo '未知錯誤';
}
switch ((string)$errId) {
case '0': echo '錯誤碼 0'; break;
case '1': echo '錯誤碼 1'; break;
default: echo '未知錯誤';
}
$msg = match ((string)$errId) {
'0' => '錯誤碼 0',
'1' => '錯誤碼 1',
default => '未知錯誤',
};
echo $msg;
match 採用嚴格比較(===),無 break、無落穿、可直接返回值,強烈建議 PHP 8+ 專案全面替代 switch。
$cps = 'yiqifa';
switch ($cps) {
case 'yiqifa':
case 'chengguo':
case 'roiyiqifa':
case 'lkt':
// 這些平台共用同一邏輯
$sql = "INSERT ...";
break;
default:
// 其他平台
}
switch 略快;複雜條件或需嚴格比較用 match 或 if。match 表達式。break、return 或 throw 結束,防止落穿。