淺談PHP中output_buffering_php技巧

來源:互聯網
上載者:User

一、我們要說一下php中的緩衝大概有哪些!

在PHP中,我們可以粗略的將緩衝分為用戶端緩衝(Browser緩衝),伺服器端緩衝(Server緩衝)。由於PHP是基於B/S架構的,所以,我們可以理解為瀏覽器端的緩衝,伺服器端緩衝。
在伺服器端PHP內建的緩衝中,主要可以分為兩大類緩衝!程式緩衝和OB緩衝!這也是我們學習伺服器端緩衝的主要內容!

在PHP中緩衝的輸出順序為:
開啟了php輸出緩衝: echo,print -> php output_buffering -> server buffering -> browser buffering -> browser display

未開啟php輸出緩衝: echo,print -> server buffering -> browser buffering -> browser display

瀏覽器的輸出緩衝:IE為256Bytes, Chrome與FireFox為1000Bytes,只有輸出資料達到了這個長度或者指令碼結束瀏覽器才會將資料輸出在頁面上。

二、伺服器端的響應流程

A、用戶端向伺服器端發送請求響應!
B、Apache伺服器載入了PHP模組,開啟相應的進程(或線程)運行相應的PHP指令碼頁面!
C、在沒有開啟OB緩衝的情況下,啟動並執行結果全部都會被放到程式緩衝中,然後打包發送給瀏覽器!瀏覽器對頁面進行渲染,產生我們最後看到的WEB頁面!
D、在開啟了OB緩衝的情況下,啟動並執行結果會被分別放入到OB緩衝和程式緩衝中,當程式運行到最後一行的時候,就會將OB緩衝中的資料刷回到程式緩衝中,然後打包返回給瀏覽器!瀏覽器對頁面進行渲染,產生我們看到的WEB頁面!

三、OB緩衝的常見用法!

a、output_buffering=4096,輸出較少的資料(少於一個buffer)

for($i=0; $i<5; $i++){  echo $i.'<br>';  sleep(1);  }

運行結果:等所有指令碼全部運行完成後,才輸出,因為資料未滿一個buffer的大小。

b、output_buffering=4096,輸出較少的資料(少於一個buffer),關閉output_buffering,修改php.ini的output_buffering=0

echo str_repeat(" ",1024);//這裡重複輸出一個空白for($i=0; $i<5; $i++){ echo $i."<br/>";  flush();   sleep(1); }

運行結果:因為禁用了OB,不需要等到指令碼運行完畢就可以輸出,資料沒有在OB停留,可以看到斷斷續續間歇性輸出。echo ->browser buffering -> browser display

c、output_buffering=4096,輸出較大資料(大於一個buffer),不使用ob_start()

for($i=0; $i<5; $i++){   echo file_get_contents('f.txt').$i.'<br/><br/><br/><br/>';   sleep(2); }

運行結果:f.txt為一個大於4kb的檔案,因為大於buffer預設值,buffer空間不夠用,每當滿一個buffer就會輸出,所以可以看到間歇性輸出。

d、output_buffering=4096,輸出較大資料(大於一個buffer),使用ob_start()

ob_start(); for($i=0; $i<5; $i++){   echo file_get_contents('f.txt').$i.'<br/><br/><br/><br/>';   sleep(2); }

運行結果:因為使用了ob_start(),會為buffer設定足夠大的空間,因此會儲存到指令碼執行完畢後才會輸出。

e、output_buffering=On,使用ob_start()

ob_start();echo "abc-";header("content-type:text/html;charset=utf-8");echo "hello-";ob_end_flush();echo "aa-";echo ob_get_contents();

運行結果:abc-hello-aa-abc-hello-aa-

f、output_buffering=Off,使用ob_start()

ob_start();echo "abc-";header("content-type:text/html;charset=utf-8");echo "hello-";ob_end_flush();echo "aa-";echo ob_get_contents();

運行結果:abc-hello-aa-

輸出緩衝區是可堆疊的,這即意謂著,當有一個 ob_start() 是活躍的時, 你可以調用另一個 ob_start() 。 只要確保又正確調用了 ob_end_flush() 恰當的次數即可。 如果有多重輸出回呼函數是活躍的,輸出內容會一直按嵌套的順序依次通過它們而被過濾。

注意:PHP5.2中,OB預設是關閉的,5.3之後預設是開啟的;

常用方法:

1.ob_start
啟用output_buffering機制,一旦啟用,指令碼不再直接輸出到瀏覽器,而是暫時寫入php buffering地區。直到指令碼運行完畢後,才發送。

2.ob_get_contents
擷取php buffering中的資料,注意:要在ob_end_clean()前調用,否則只會得到Null 字元。

3.ob_end_flush 和 ob_end_clean
ob_end_flush 會輸出php buffering 中的資料,但不會清空。
ob_end_clean 不會輸出,只會清空php buffering中的資料。

4.ob_flush 、flush、ob_implicit_flush
ob_flush 會重新整理php buffering 中的資料到程式緩衝

flush 則會重新整理程式緩衝到瀏覽器緩衝中

ob_implicit_flush 將開啟或關閉絕對(隱式)刷送。絕對(隱式)刷送將導致在每次輸出調用後有一次刷送操作,以便不再需要對 flush() 的顯式調用

四、OB緩衝的作用!

OB緩衝在各個方面都有應用,但是,本人知道的主要是在兩個方面!
a、當網站準備做網站靜態化的時候,選擇OB緩衝是一個不錯的選擇!

b、解決Warning: Cannot modify header information - headers already sent by的錯誤!
究其發生錯誤的原因:是因為回應標頭和相應主體位置錯位導致的!正常情況下,伺服器返回給瀏覽器的相應內容,應該是:回應標頭+響應主體!

但是,如果我們開啟了OB緩衝,那麼相應頭資訊(一般也就是header()函數進行設定的資訊),會被放入到程式緩衝中!
而其他的輸出內容,如:echo print_r var_dump 等,都會先被放入OB緩衝中!
等程式結束的時候,或者OB緩衝關閉的實話,將OB緩衝的內容在放入程式緩衝中!從而保證回應標頭資訊,始終在響應主體內容之前!

以上所述就是本文的全部內容了,希望大家能夠喜歡。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.