1. 程式人生 > >解決Warning: Cannot modify header information

解決Warning: Cannot modify header information

資訊的時候經常提示:cannot modify header information - headers already sent by (......)。其實已經實現需要的效果了,就是這個錯誤資訊看著不爽,網上找了很多辦法,綜合使用得到的解決方法是

1在頁面頂部的php標籤中加入ob_start();

2在返回的資訊下面加入ob_end_flush();

這樣就可以遮蔽錯誤資訊的現實了

另外轉一下其他人的方法,也許在其他情況下也會有效

If you got this message: "Warning: Cannot modify header information - headers already sent by ...."
如果在執行php程式時看到這條警告:"Warning: Cannot modify header information - headers already sent by ...."

Few notes based on the following user posts:
有以下幾種解決方法:

1. Blank lines (空白行):
Make sure no blank line after <?php ... ?> of the calling php script.
檢查有<?php ... ?> 後面沒有空白行,特別是include或者require的檔案。不少問題是這些空白行導致的。

2. Use exit statement (用exit來解決):
Use exit after header statement seems to help some people
在header後加上exit();


header ("Location: xxx");
exit();

3. PHP has this annoying problem, if your HTML goes before any PHP code or any header modification before redirecting to certain page, it'll said "Warning: Cannot modify header information - headers already sent by ...." Basically anytime you output to browser, the header is set and cannot be modified.   So two ways to get around the problem:

3a. Use Javascript (用Javascript來解決):
<? echo "<script> self.location(/"file.php/");</script>"; ?>
Since it's a script, it won't modify the header until execution of Javascript.
可以用Javascript來代替header。但是上面的這段程式碼我沒有執行成功... 另外需要注意,採用這種方法需要瀏覽器支援Javascript.

3b. Use output buffering (用輸出快取來解決):
<?php ob_start(); ?>
... HTML codes ...
<?php
... PHP codes ...
header ("Location: ....");
ob_end_flush();
?>
This will save the output buffer on server and not output to browser yet, which means you can modify the header all you want until the ob_end_flush() statement.   This method is cleaner than the Javascript since Javascript method assumes the browser has Javascript turn on.   However, there are overhead to store output buffer on server before output, but with modern hardware I would imagine it won't be that big of deal.   Javascript solution would be better if you know for sure your user has Javascript turn on on their browser.

就像上面的程式碼那樣,這種方法在生成頁面的時候快取,這樣就允許在輸出head之後再輸出header了。本站的許願板就是採用這種方法解決的header問題。

後臺管理或者有時候在論壇,點選一個頁面,頁頂會出現
Warning: Cannot modify header information - headers already sent by....
這類語句,造成這個原因是因為setcookie語句的問題。

cookie本身在使用上有一些限制,例如:
1.呼叫setcookie的敘述必須放在<html>標籤之前
2.呼叫setcookie之前,不可使用echo
3.直到網頁被重新載入後,cookie才會在程式中出現
4.setcookie函式必須在任何資料輸出至瀏覽器前,就先送出
5.……
基於上面這些限制,所以執行setcookie()函式時,常會碰到"Undefined index"、"Cannot modify header information - headers already sent by"…等問題,解決"Cannot modify header information - headers already sent by"這個錯誤的方法是在產生cookie前,先延緩資料輸出至瀏覽器,因此,您可以在程式的最前方加上ob_start();這個函式。這樣就可以解決了。

4.set output_buffering = On in php.ini (開啟php.ini中的output_buffering )
set output_buffering = On will enable output buffering for all files. But this method may slow down your php output. The performance of this method depends on which Web server you're working with, and what kind of scripts you're using.
這種方法和3b的方法理論上是一樣的。但是這種方法開啟了所有php程式的輸出快取,這樣做可能影響php執行效率,這取決於伺服器的效能和程式碼的複雜度。

昨天想用PHP寫一段下載檔案的程式碼,因為不想得怎麼設定HTTP協議就直接到php.net上找header()函式的事例,很多程式碼,我直接拷貝了一段,

<?php
$file='filetest.txt';//filetest.txt檔案你隨便寫點東西進去就好了
header("Content-Disposition: attachment; filename=".urlencode($file));   
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Description: File Transfer");            
header("Content-Length: ".filesize('filetest.txt'));
flush(); // this doesn't really matter.

$fp=fopen($file,"r");
while (!feof($fp))
{
    
echofread($fp,65536);
    
flush(); // this is essential for large downloads
}

fclose($fp);

?>

運行了一下發現不行,一直報錯:Warning: Cannot modify header information - headers already sent by (output started at E:/xampp/htdocs/test/downloadfile/file_download.php:1) in E:/xampp/htdocs/test/downloadfile/file_download.php on line 3

我很看了很久,檔案一開始就直接是header程式碼了,沒任何輸出怎麼會說已有字元輸出了呢?後來上網查到別人給的提示,才發現,原來我建立檔案的時候是直接用記事本儲存為UTF8, 原來這樣也會出錯

----------------以下是引用他人的建議 --------------------

方法一:
在PHP裡Cookie的使用是有一些限制的。
1、使用setcookie必須在<html>標籤之前
2、使用setcookie之前,不可以使用echo輸入內容
3、直到網頁被載入完後,cookie才會出現
4、setcookie必須放到任何資料輸出瀏覽器前,才送出
.....
由於上面的限制,在使用setcookie()函式時,學會遇到 "Undefined index"、"Cannot modify header information - headers already sent by"…等問題,解決辦法是在輸出內容之前,產生cookie,可以在程式的最上方加入函式 ob_start();

ob_start :開啟輸出緩衝區
函式格式:void ob_start(void)
說明:當緩衝區啟用時,所有來自PHP程式的非檔案頭資訊均不會發送,而是儲存在內部緩衝區。為了輸出緩衝區的內容,可以使用ob_end_flush()或flush()輸出緩衝區的內容。


方法二:
解 決Warning: Cannot modify header information - headers already sent by ...... 前幾天裝了個php的大頭貼系統測試,發現報錯Warning: Cannot modify header information - headers already sent by ......
今天又裝openads,還是出現這個問題。怒了。上網找了半天,有人說要在檔案開頭寫上
ob_start();
失敗。
後來開啟 php.ini 然後把 output_buffering 設為 on 。重起appache,OK。看來這才是解決辦法。

特別注意:(我就是看了這個才解決問題的)如果使用utf-8編碼,一定要去掉UTF-8中的BOM,這都是因為utf-8編碼檔案含有的bom原因,而php4,5都是不支援bom的。去掉bom,可以用Notepad++開啟轉換一下。(我就是看了這個才解決問題的)

用PHP的ob_start(); 控制您的瀏覽器cache 。