header 之前有輸入會導致錯誤的原因

一直只知道不能有輸出,具體理由還不知道。今天明白了。

 

 由於 目前對 http 協議不是很清楚,所以不能具體說明。

 

例子:test.php

echo 'test';
header('content-type:text/html;charset=utf-8');


上面的代碼 在 php.ini 中

output_buffering=Off 的時候會導致一個錯誤(關閉php默認緩存)

test.php 在執行的時候由於php緩存被關閉,所以他直接先把 test 輸出 然後在去修改 頭信息。

 

http協議有2個部分,一個是頭信息部分和主題(body)部分,應該要先將頭信息輸出後在輸出主題

由於在代碼中 header不再第一行,因此 在訪問 test.php 的時候 已經把頭信息給輸出掉了。

然後輸出 test 之後在試圖修改 頭信息 此時已經無法修改頭信息了 因此我們能看到這樣一段錯誤

Warning: Cannot modify header information - headers already sent by (output started at D:\PHPnow-1.5.6\htdocs\test.php:2) in D:\PHPnow-1.5.6\htdocs\test.php on line 4


大概意思是在說 頭信息無法修改。

下面抓包的圖

 

頭信息 content-type 爲 text/html; 因爲代碼的第一行不是 header 解釋時可能是認爲沒有對頭信息進行修改 所以直接先輸出了默認的頭信息

 

在看下面的圖

正文部分 輸出了 11 之後 才發現 有一段 header 代碼 試圖修改了頭信息,因爲 頭信息已經輸出掉了 所以無法進行修改。

這只是一個警告非錯誤。

如果在php關閉了默認緩存的情況下 讓上面的代碼不發生錯誤 可以使用 php 緩存函數

ob_start();
echo 'test';
header('content-type:text/html;charset=utf-8');
echo 'tests';


 

ob_start 開啓環迅,將頁面的所有輸出都丟到緩衝區。

此時 因爲頁面的輸出會保存到緩衝區中 所以在執行 header 之前是沒有任何輸出。

那麼在什麼時候纔會把緩衝區的內容釋放出來呢? 應該是 4096 字節滿了就會釋放(這個好像可以修改)

要麼手動釋放。 如何判斷他們是在緩衝區而沒有輸出?

 

$str = ob_get_contents();


他能返回緩衝區的內容,可以把這個內容寫入到一個文件中進行查看。

 

順便將常見的 緩存函數列出來

 

ob_clean -- > 清空緩衝區

ob_end_clen()  --> 關閉緩衝同時清空緩衝區

ob_end_flush()  --> 關閉緩存並輸出緩衝區的內容

ob_flush()   --> 輸出緩衝區的內容 並清空緩衝區

flush();  --> 刷新程序緩存( 他是程序緩存,不是 ob緩存,php有2個緩存,一個是ob 一個是 程序)

 

for($i = 0; $i < 3; $i++) {
	echo str_repeat(' ' , 256);
	echo $i;
	sleep(1);
	flush();
}


 

這段代碼如果沒有flush (刷新程序緩存) 那麼會等待50秒後才顯示 0 - 49

因爲循環沒有結束時會把所有的 echo 都丟到 程序緩存中,當循環結束後 纔會刷新程序緩存 把 0 - 49 一口氣顯示

 

但是現在每等待1秒中就刷新了程序緩存 所以 按道理 應該每過一秒就得看到一個數字被打印纔對,但是使用看不到 還是和原來一樣。

其實這不是 flush的問題,他確實刷新了程序緩存,只不過(如果你用的是ie) 瀏覽器也有自己的緩存,當頁面輸出的內容少於  256個字節時

是不會顯示到文檔中,這段代碼稍微修改

for($i = 0; $i < 3; $i++) {
	echo str_repeat(' ' , 256);
	echo $i;
	sleep(1);
	flush();
}


 

在輸出 $i 之前 先打印 256個空字符 之後在輸出 $i 則能看到效果。
發佈了41 篇原創文章 · 獲贊 1 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章