goto 是 PHP 5.3+ 引入的跳轉操作符,允許在**同一檔案、同一作用域**內跳轉到標籤位置。雖然結構化程式設計原則不建議濫用,但在「跳出多層巢狀循環/switch」場景下,goto 能以極少代碼替代多層 break 或旗標變量,提升可讀性。
<?php
goto label;
echo '這行會被跳過';
label:
echo '落地執行';
名稱: (冒號結尾)switch/try-catch 區塊,只能跳**出**<?php
for ($i = 0, $j = 50; $i < 100; $i++) {
while ($j--) {
if ($j === 17) goto END; // 直接跳出雙層循環
}
}
echo "i = $i"; // 不會執行
END:
echo 'j hit 17'; // 執行這裡
對比傳統寫法:
<?php
$stop = false;
for ($i = 0; $i < 100 && !$stop; $i++) {
for ($j = 50; $j >= 0 && !$stop; $j--) {
if ($j === 17) $stop = true;
}
}
// 需額外旗標、多層判斷、變數汙染外層作用域
<?php
function process($data) {
if (!validate_step1($data)) goto ERROR;
if (!validate_step2($data)) goto ERROR;
if (!save_to_db($data)) goto ERROR;
return true;
ERROR:
log_error('Process failed');
return false;
}
類似 C 語言的 goto cleanup 模式,將錯誤處理集中在函數尾部,避免巢狀 if-else。
| 限制 | 說明 |
|---|---|
| 跨函數/方法 | ❌ 不允許 |
| 跨檔案 | ❌ 不允許 |
| 跳入循環/switch/try-catch | ❌ 致命錯誤 |
| 跳出循環/switch/try-catch | ✅ 允許 |
| 命名空間隔離 | 標籤僅在當前命名空間可見 |
break/continue 足夠時不要用 goto。END_LOOP、ERROR_EXIT、CLEANUP,避免 a: b: 這類無意義標籤。yield 往往能更優雅解決同樣問題。合理使用 goto 是「工具箱裡的手術刀」而非「瑞士刀」,精準切除多層跳出的煩瑣,但濫用會割傷代碼可維護性。