PHP 重新導向 (Redirect) 是表單提交後、登入驗證後、權限不足時常用操作。本文詳細比較三種方法的原理、適用場景、優缺點與最佳實踐。
<?php
$target = 'success.php'; // 可來自資料庫動態決定
header('Location: ' . $target);
exit; // 關鍵:阻止後續代碼執行
?>
<?php
echo '<script>window.location.href = "success.php";</script>';
// 或
echo '<script>window.location.replace("success.php");</script>'; // 不留歷史紀錄
?>
<?php
echo '<meta http-equiv="refresh" content="0; url=success.php">';
// content="秒數; url=目標",0 秒即時跳轉
?>
| 維度 | Header Location | JavaScript | Meta Refresh |
|---|---|---|---|
| HTTP 狀態碼 | 302 (預設) / 301 | 200 + JS 執行 | 200 + Meta |
| 執行時機 | Header 階段 (輸出前) | DOM 載入後 | HTML 解析時 |
| 瀏覽器歷史 | 不留 (302) / 留 (301) | 留 (`href`) / 不留 (`replace`) | 留 |
| SEO 友善 | 最佳 | 一般 | 差 |
| 相依性 | 無 | 需 JS 啟用 | 無 |
| 彈性 | 低 (需輸出前) | 高 (可延遲、條件判斷) | 低 |
<?php
function redirect(string $url, int $statusCode = 302): never {
// 1. 確保無輸出
if (headers_sent($file, $line)) {
// 備援:JS 重導向
echo '<script>window.location.replace(' . json_encode($url) . ');</script>';
exit;
}
// 2. 發送標準 Header
http_response_code($statusCode);
header('Location: ' . $url);
exit;
}
// 使用
if ($loginSuccess) {
redirect('dashboard.php');
} elseif ($permissionDenied) {
redirect('403.php', 403);
}
**Header Location 是標準首選**,JavaScript 為輸出後備援,Meta Refresh 僅作極舊環境相容。封裝 `redirect()` 函式統一處理狀態碼、備援邏輯與輸出檢查,能避免 99% 重導向相關 Bug。