PHP 透過 header() 函數發送 HTTP 標頭指令瀏覽器執行導向。兩種主要模式:立即導向(302 Found)與延遲導向(Refresh 標頭)。
header('Location: https://example.com/target.php');
// 關鍵:必須立即終止腳本執行
die(); // 或 exit();
// 完整範例
if (!isset($_SESSION['user_id'])) {
header('Location: /login.php?redirect=' . urlencode($_SERVER['REQUEST_URI']));
die();
}
header() 必須在任何輸出之前呼叫(包含空白、BOM、echo、HTML 標籤)。否則觸發「Headers already sent」警告並導向失敗。
// 方法 1:腳本開頭啟用
ob_start();
// ... 任意輸出操作 ...
header('Location: /target.php');
ob_end_flush(); // 釋放緩衝並發送
// 方法 2:php.ini 設定(全域生效)
// output_buffering = 4096
適用於顯示提示訊息、倒數計時等情境:
header('Refresh: 3; url=/dashboard.php');
echo '登入成功,3 秒後跳轉...';
die();
HTML 替代方案(無輸出限制):
登入成功,3 秒後跳轉...
/**
* 統一導向函數
*
* @param string $url 目標 URL
* @param string|null $msg 提示訊息(null 為立即導向)
* @param int $seconds 延遲秒數(僅 $msg 非 null 時生效)
*/
function redirect(string $url, ?string $msg = null, int $seconds = 3): never {
if ($msg === null) {
header("Location: {$url}");
} else {
// 使用 HTML meta 導向,支援自訂樣式
header("Content-Type: text/html; charset=utf-8");
echo <<
頁面跳轉中...
{$msg}
{$seconds} 秒後自動跳轉... 點此手動跳轉
HTML;
}
exit; // never 回傳型別(PHP 8.1+)
}
| 場景 | 實作要點 |
|---|---|
| 登入後返回原頁 | 儲存 $_SERVER['REQUEST_URI'] 到 Session,登入成功後讀取導向 |
| POST-Redirect-GET (PRG) 模式 | 表單提交處理完畢導向 GET 頁面,防止重複提交 |
| 多語系導向 | 根據 Accept-Language 或 Session 語系偏好導向對應語言頁面 |
| 維護模式 | 中介層檢查維護旗標,非管理員導向維護頁面 |
301 Moved Permanently:永久遷移(SEO 權重轉移)302 Found (預設):暫時導向303 See Other:PRG 模式推薦,強制 GET 請求307 Temporary Redirect:保持原請求方法308 Permanent Redirect:永久且保持方法header('Location: /new-url.php', true, 301); // 明確指定 301