發送原生 HTTP 頭

header

(PHP 4, PHP 5, PHP 7, PHP 8)

header發送原生 HTTP 頭

說明

header(string $string, bool $replace = true, int $response_code = ?): void

header() 用於發送原生的 HTTP 頭。關於 HTTP 頭的更多資訊請參考 » HTTP/1.1 specification

請注意 header() 必須在任何實際輸出之前呼叫,不管是普通的 HTML 標籤,還是檔案或 PHP 輸出的空行,空格。這是個常見的錯誤,在通過includerequire,或者其訪問其他檔案裡面的函式的時候,如果在header()被呼叫之前,其中有空格或者空行。 同樣的問題也存在於單獨的 PHP/HTML 檔案中。

<html>
<?php
/* This will give an error. Note the output
 * above, which is before the header() call */
header('Location: http://www.example.com/');
exit;
?>

參數

string

頭字串。

有兩種特別的頭。第一種以「HTTP/」開頭的 (case is not significant),將會被用來計算出將要發送的HTTP狀態碼。 例如在 Apache 伺服器上用 PHP 指令碼來處理不存在檔案的請求(使用 ErrorDocument 指令), 就會希望指令碼響應了正確的狀態碼。

<?php
// 本示例演示了 "HTTP/" 的特殊例子,典型用法的最佳實踐,包括:
// 1. header($_SERVER["SERVER_PROTOCOL"] . " 404 Not Found");
//    (覆蓋 http 狀態訊息,相容還在使用 HTTP/1.0 的客戶端)
// 2. http_response_code(404); (使用預設訊息)
header("HTTP/1.1 404 Not Found");
?>

第二種特殊情況是「Location:」的頭資訊。它不僅把報文發送給瀏覽器,而且還將返回給瀏覽器一個 REDIRECT(302)的狀態碼,除非狀態碼已經事先被設定爲了201或者3xx

<?php
header
("Location: http://www.example.com/"); /* Redirect browser */

/* Make sure that code below does not get executed when we redirect. */
exit;
?>
replace

可選參數 replace 表明是否用後面的頭替換前面相同型別的頭。 預設情況下會替換。如果傳入 false,就可以強制使相同的頭資訊並存。例如:

<?php
header
('WWW-Authenticate: Negotiate');
header('WWW-Authenticate: NTLM'false);
?>
response_code

強制指定 HTTP 響應的值。注意,這個參數只有在報文字串(header)不為空的情況下才有效。

返回值

沒有返回值。

錯誤/異常

當 header 發送失敗時,header() 會拋出 E_WARNING 級別的錯誤

範例

示例 #1 下載對話方塊

如果你想提醒使用者去儲存你發送的數據,例如儲存一個產生的PDF檔案。你可以使用» Content-Disposition的報文資訊來提供一個推薦的檔名,並且強制瀏覽器顯示一個檔案下載的對話方塊。

<?php
// 輸出 PDF 檔案
header('Content-type: application/pdf');

// 名稱為 downloaded.pdf
header('Content-Disposition: attachment; filename="downloaded.pdf"');

// 該 PDF 來源於 original.pdf
readfile('original.pdf');
?>

示例 #2 快取指令

PHP 指令碼經常產生一些動態內容,它不該被客戶端、伺服器與瀏覽器之間的代理快取。 許多代理與客戶端都支援這樣強制禁用快取:

<?php
header
("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // 過去的日期
?>

注意:

也許你會遇到這樣的情況,那就是即使你沒使用上面這段程式碼,你的頁面也沒有被快取。大多數情況是因為使用者可以自己設定他們的瀏覽器從而改變瀏覽器預設的快取行為。一旦發送了上面這段報文資訊,那麼你就應該重寫那些可能用到快取了的程式碼。

此外,在啟用session的情況下,session_cache_limiter()session.cache_limiter的配置可以用來自動地產生正確的快取相關的頭資訊。

註釋

注意:

數據頭只會在SAPI支援時得到處理和輸出。

注意:

你所有需要輸出到瀏覽器的數據將會一直快取在伺服器端,直到你發送他們,這將造成比較大的資源開銷。你可以是用輸出緩衝來避開這個問題。你可以通過在指令碼里使用ob_start()ob_end_flush()或者直接在你的php.ini檔案里設定output_buffering,也可以直接在伺服器的配置檔案里設定。

注意:

HTTP狀態資訊的報文永遠都是最新被髮送到客戶端的,而不管header()是否是在最先發送的。報文狀態碼可能會被重寫,當呼叫header()來設定新的狀態碼,除非HTTP報文已經被髮送了。

注意:

絕大多數現代瀏覽器的 » Location: 都支援相對 URI,但也有一些舊瀏覽器需要絕對 URI:包含協議、主機名、絕對路徑。 一般情況下,可以藉助 $_SERVER['HTTP_HOST']$_SERVER['PHP_SELF']dirname() 將相對地址組合成絕對 URI:

<?php
/* 根據目前請求所在的目錄,重定向到不同的頁面 */
$host  $_SERVER['HTTP_HOST'];
$uri   rtrim(dirname($_SERVER['PHP_SELF']), '/\\');
$extra 'mypage.php';
header("Location: http://$host$uri/$extra");
exit;
?>

注意:

在執行Location header跳轉的時候,Session ID無法通傳遞的,即使session.use_trans_sid是啟用狀態的。只能通過手動傳遞using SID的值來實現。

參見

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *