發送頭訊息前不能有任何輸出
任何修改或者發送HTTP頭的函數都必須在 任何形式的輸出 之前被調用
一些函數會修改HTTP頭:
header/header_remove
session_start/session_regenerate_id
setcookie/setrawcookie
而輸出主要可能如下:
隱性輸出
在 <?php 之前或者 ?> 之後的空格
UTF-8檔案的 BOM頭
之前出現的報錯資訊
顯性輸出
print , echo 和其它類似的輸出函數
在 <?php 之間嵌入的原始html
為什麼會出現Cannot modify header information – headers already sent by錯誤
為了理解為什麼頭訊息必須早於輸出,我們來看看典型的HTTP響應。PHP主要是產生HTML內容,但同時也傳輸了一組 HTTP/CGI 頭給webserver:
HTTP/1.1 200 OK
Powered-By: PHP/5.3.7
Vary: DontTrackMeHere
Content-Type: text/html; charset=utf-8
<html><head><title>PHP page output page</title></head>
<body><h1>Content</h1> <p>Some more output follows...</p>
and <a href="/"> <img src=internal-icon-delayed> </a>
輸出總是尾隨頭訊息出現。PHP必須首先傳頭訊息給網頁伺服器,並且只能傳一個。在兩個換行之後再也不能為頭訊息添加任何內容了。
當PHP收到第一個輸出後(例:print,echo,…),它會重新整理並發送設定的所有頭資訊。然後就可以就可以隨心所欲的輸出了,但是此時已經無法修改HTTP頭資訊了。
如何找到早於頭訊息的輸出
報錯資訊中已經包含了所有相關能夠定位錯誤的資訊:
Warning: Cannot modify header information - headers already sent by (output started at /www/usr2345/htdocs/auth.php:52) in /www/usr2345/htdocs/index.php on line 100
可以看到header在檔案的100行被調用。
“output started at” 則包含著更重要的資訊:直接指名在auth.php的52行已經產生了輸出。這就是我們需要找的。
一般情況:
print,echo
原始的HTML語句
<!DOCTYPE html>
<?php
//已經不能修改或發送頭訊息了
<?php 之前的空格
<?php
//這裡有一個空格
UTF-8 BOM
這是更不易察覺,但比較普遍出現的情況。確保用你的編輯器儲存檔案以“UTF-8 (no BOM)”方式儲存。
報錯資訊形如 “Unknown on line 0”
一般這樣的報錯說明輸出來自PHP擴充或者PHP.ini設定錯誤資訊