首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP header() 重定向失效?常見原因與解決方案完整指南

     編輯:PHP 相關知識

在 PHP 開發中,header() 函數是實現頁面跳轉、設定 HTTP 標頭、控制快取等核心操作的關鍵工具。然而,許多開發者常遇到「重定向不生效」或跳出 Warning: Cannot modify header information - headers already sent 的錯誤。本文將系統梳理 header() 的核心用法、常見失敗原因,並提供最佳實踐方案。

一、header() 函數的核心功能

header() 用於發送原始 HTTP 標頭,主要用途包括:

  1. 頁面重定向:透過 Location 標頭讓瀏覽器自動跳轉至指定 URL。
  2. 設定內容類型:如 Content-Type: application/json、application/pdf 等,告訴瀏覽器如何解析回應內容。
  3. 檔案下載控制:搭配 Content-Disposition: attachment 強制瀏覽器下載而非直接開啟。
  4. HTTP 狀態碼控制:如 301 永久重定向、404 未找到、401 未授權等。
  5. 快取控制:設定 Cache-Control、Expires、Pragma 等標頭。

二、語法與參數詳解

header(string $header, bool $replace = true, int $http_response_code = 0): void
  • $header:要發送的標頭字串(必填)。
  • $replace:是否替換同類型的前一個標頭,預設 true;設為 false 可發送多個同名標頭。
  • $http_response_code:強制指定 HTTP 回應碼(PHP 4.3+ 可用)。

三、經典使用範例

1. 基礎重定向(務必加上 exit)

<?php
header("Location: https://www.example.com/");
exit; // 防止後續程式碼繼續執行
?>

2. 禁止快取,強制瀏覽器獲取最新內容

<?php
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-cache, must-revalidate");
header("Pragma: no-cache"); // HTTP/1.0 相容
?>

3. 輸出 HTTP 狀態碼(權限控制、偽裝 404)

<?php
// 401 未授權
header('HTTP/1.1 401 Unauthorized');
header('Status: 401 Unauthorized');

// 偽裝 404(注意寫法)
header('HTTP/1.1 404 Not Found');
// header("Status: 404 Not Found"); // 此寫法在某些環境下可能無效
?>

4. 檔案下載(隱藏真實路徑)

<?php
header("Content-Type: audio/mpeg");
header('Content-Disposition: attachment; filename="song.mp3"');
header("Content-Description: PHP Generated Data");
readfile('/path/to/real/song.mp3');
?>

四、重定向失效的「頭號殺手」:headers already sent

錯誤訊息:

Warning: Cannot modify header information - headers already sent by (output started at /path/file.php:12) in /path/file.php on line 20

根本原因

PHP 執行機制:腳本啟動時,HTTP 標頭與主體內容分開發送。標頭會被暫存於列表中,直到腳本輸出第一個非標頭內容(HTML 文字、echo、print、空白行、BOM 標記等),PHP 才會一次性發送所有標頭並結束標頭階段。此後再呼叫 header()、setcookie()、session_start() 皆會觸發錯誤。

常見輸出來源

  • <?php ... ?> 標籤間的空白行、換行
  • PHP 起始標籤前的任何字元(含 BOM)
  • echo、print、var_dump 等輸出語句
  • 錯誤/警告訊息輸出到畫面
  • include/require 的檔案中有輸出

解決方案

  1. 嚴格檢查輸出順序:確保 header() 呼叫前零輸出,包含空白字元。
  2. 啟用輸出緩衝:
    • 修改 php.ini:output_buffering = 4096(或 On)
    • 或在程式碼最開頭加入 ob_start(),結尾 ob_end_flush()

    原理:開啟緩衝後,輸出不會直接送至瀏覽器,而是暫存於記憶體緩衝區,標頭仍可隨時修改;腳本結束時 PHP 自動先送標頭再送內容。

  3. 移除 BOM:使用支援「UTF-8 無 BOM」編碼的編輯器儲存檔案。
  4. 重定向後立即 exit:防止後續邏輯產生輸出干擾。

五、HTTP 狀態碼速查

範圍含義
1xx資訊回應(保留)
2xx成功(200 OK、201 Created)
3xx重定向(301 永久、302 暫時、304 Not Modified)
4xx用戶端錯誤(400 Bad Request、401 Unauthorized、403 Forbidden、404 Not Found)
5xx伺服器錯誤(500 Internal Server Error、502 Bad Gateway、503 Service Unavailable)

六、最佳實踐清單

  • ✅ 重定向永遠使用絕對 URL(含 https://)。
  • ✅ header("Location: ...") 後緊接 exit;。
  • ✅ 專案入口檔案最頂端呼叫 ob_start(),統一管理輸出緩衝。
  • ✅ 檔案編碼統一為 UTF-8 無 BOM。
  • ✅ 避免在邏輯層混雜 HTML 輸出,採用 MVC 或模板引擎分離關注點。
  • ✅ 設定 error_reporting(E_ALL) 開發階段捕捉隱性輸出。

掌握 header() 的運作機制與輸出緩衡原理,就能徹底解決重定向失效、標頭衝突等經典難題,讓 PHP 應用更穩健、可維護。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved