PHP 輸出緩沖控制(Output Control)詳解
php 緩沖簡(jiǎn)介
其實(shí)我對(duì)php ob 系列印象還是很模糊,具體怎么玩的,還不是很了解,平時(shí)curd,確實(shí)對(duì)這些內(nèi)容沒(méi)有深入。作為phper 甚是慚愧。網(wǎng)上搜了一通,互相copy,代碼運(yùn)行不能出現(xiàn)作者所描述現(xiàn)象,本文良心出品,代碼都是作者運(yùn)行過(guò)。
當(dāng)執(zhí)行輸出的時(shí)候,比如 echo,print。輸出并沒(méi)有立即送給 web server, 而是將數(shù)據(jù)寫(xiě)入 php buffer。php output_buffering 機(jī)制好處當(dāng)然提升性能。其實(shí) php 文件最終在瀏覽器上顯示,走過(guò)3個(gè)緩沖階段: php buffer=》web server buffer=》browser buffer。 最后顯示到瀏覽器
默認(rèn)情況下,php buffer 是開(kāi)啟的,而且該 buffer 默認(rèn)值是4096,即4 kb。你可以通過(guò)在php.ini配置文件中找到output_buffering配置。buffer是一個(gè)內(nèi)存地址空間,Linux系統(tǒng)默認(rèn)大小一般為4096(4kb),即一個(gè)內(nèi)存頁(yè)。主要用于存儲(chǔ)速度不同步的設(shè)備或者優(yōu)先級(jí)不同的設(shè)備之間傳辦理數(shù)據(jù)的區(qū)域。通過(guò)buffer,可以使進(jìn)程這間的相互等待變少。這里說(shuō)一個(gè)通俗一點(diǎn)的例子,你打開(kāi)文本編輯器編輯一個(gè)文件的時(shí)候,你每輸入一個(gè)字符,操作系統(tǒng)并不會(huì)立即把這個(gè)字符直接寫(xiě)入到磁盤(pán),而是先寫(xiě)入到buffer,當(dāng)寫(xiě)滿(mǎn)了一個(gè)buffer的時(shí)候,才會(huì)把buffer中的數(shù)據(jù)寫(xiě)入磁盤(pán),當(dāng)然當(dāng)調(diào)用內(nèi)核函數(shù)flush()的時(shí)候,強(qiáng)制要求把buffer中的臟數(shù)據(jù)寫(xiě)回磁盤(pán)。
舉個(gè)例子
<?php echo "南無(wú)阿彌陀佛<br>"; header("content-type:text/html;charset='utf-8'"); echo "真善忍好!"; //output //南無(wú)阿彌陀佛 //真善忍好
header()必須在任何實(shí)際輸出之前調(diào)用,但是我們程序已經(jīng)輸出了,卻正常運(yùn)行。在看下面的代碼:
<?phpecho "南無(wú)阿彌陀佛<br>"; ob_flush(); header("content-type:text/html;charset='utf-8'"); echo "真善忍好!"; //output //南無(wú)阿彌陀佛 //Cannot modify header information - headers already sent by (output started at E:\php\test.php:3) //真善忍好
上面程序說(shuō)明程序并沒(méi)有立即輸出,而當(dāng)調(diào)用ob_flush 函數(shù)的時(shí)候才刷新緩沖,輸出。
ob_flush() 與 flush()
ob_flush() , flush() 函數(shù)php 手冊(cè)上都有詳細(xì)的說(shuō)明,你可以去查閱一下。二者的區(qū)別是:
ob_flush() 是刷新PHP自身的緩沖區(qū)
flush()是 它是刷新WebServer 服務(wù)器的緩沖。輸出到瀏覽器。但是會(huì)出現(xiàn)下面的情況:
- 個(gè)別web服務(wù)器程序,特別是Win32下的web服務(wù)器程序,在發(fā)送結(jié)果到瀏覽器之前,仍然會(huì)緩存腳本的輸出,直到程序結(jié)束為止。
- 有些Apache的模塊,比如mod_gzip,可能自己進(jìn)行輸出緩存,這將導(dǎo)致flush()函數(shù)產(chǎn)生的結(jié)果不會(huì)立即被發(fā)送到客戶(hù)端瀏覽器。
- 甚至瀏覽器也會(huì)在顯示之前,緩存接收到的內(nèi)容。例如 Netscape 瀏覽器會(huì)在接受到換行或 html 標(biāo)記的開(kāi)頭之前緩存內(nèi)容,并且在接受到 </table> 標(biāo)記之前,不會(huì)顯示出整個(gè)表格。
- 一些版本的 Microsoft Internet Explorer 只有當(dāng)接受到的256個(gè)字節(jié)以后才開(kāi)始顯示該頁(yè)面,所以必須發(fā)送一些額外的空格來(lái)讓這些瀏覽器顯示頁(yè)面內(nèi)容。
比如:
<?php /** Server:LightTPD/1.4.28 (Win32) X-Powered-By:PHP/5.3.27 */ echo '佛法無(wú)邊'."<BR>"; ob_flush(); flush(); sleep(1); echo '法輪常轉(zhuǎn)'; //output
上面的代碼 在 chrome 瀏覽器上面 是一行一行的輸出,在ie系列的瀏覽器則是全部輸出。其實(shí)就是上面的 第四條一些瀏覽器只有當(dāng)接收256個(gè)字符才開(kāi)始顯示。把上面的代碼改成下面形式:
<?php /** Server:LightTPD/1.4.28 (Win32) X-Powered-By:PHP/5.3.27 */ echo str_pad('',240)."\n"; echo '佛法無(wú)邊'."<BR>"; ob_flush(); flush(); sleep(1); echo '法輪常轉(zhuǎn)'; //output
這樣在ie下面就會(huì)一行一行輸出,因?yàn)槌^(guò)256個(gè)字符。
ob 其他函數(shù)說(shuō)明
1.ob_end_flush 與 ob_end_clean
end 的顧名思義就結(jié)束,關(guān)閉緩沖區(qū),都是關(guān)閉輸出緩沖,一個(gè)是輸出緩沖區(qū),一個(gè)是清除。比如
<?php /** Server:LightTPD/1.4.28 (Win32) X-Powered-By:PHP/5.3.27 */ echo 'before'; ob_end_clean(); echo str_pad('',4096)."\n"; for ($i=10; $i>0; $i--) { echo $i; sleep(1); }
上述代碼是一下輸出全部?jī)?nèi)容,而不是一個(gè)一個(gè)輸出。ob_end_clean() 不是關(guān)閉了緩沖了?怎么不是一個(gè)一個(gè)輸出呢,其實(shí)我們上面也說(shuō)了,php 不是直接輸出給瀏覽器,而是 web server。 雖然php 沒(méi)有了 緩沖。但是web server 還是有的。所以下面代碼:
/** Server:LightTPD/1.4.28 (Win32) X-Powered-By:PHP/5.3.27 */ echo 'before'; ob_end_clean(); echo str_pad('',4096)."\n"; for ($i=10; $i>0; $i--) { flush(); echo $i; sleep(1); }
加上flush(),就會(huì)一行一行輸出。 如果把ob_end_clean 換成 ob_end_flush 會(huì)把 before 輸出來(lái)。
其他函數(shù) 可參考手冊(cè),比較簡(jiǎn)單。
總結(jié)
php 腳本到瀏覽器,要經(jīng)過(guò) php buffer=》web server buffer=》browser buffer。 最后顯示到瀏覽器。 缺一不可。 所以我們要 ob_flush 和 flush 以及加上 echo str_pad('',4096) 才能調(diào)試出你想要的效果。
以上就是對(duì)PHP 緩沖的資料整理后續(xù)繼續(xù)補(bǔ)充相關(guān)資料,謝謝大家對(duì)本站的支持!
相關(guān)文章
PHP編程獲取音頻文件時(shí)長(zhǎng)的方法【基于getid3類(lèi)】
這篇文章主要介紹了PHP編程獲取音頻文件時(shí)長(zhǎng)的方法,通過(guò)引入第三方getid3類(lèi)來(lái)實(shí)現(xiàn)操作音頻文件的功能,需要的朋友可以參考下2017-04-04PHP隨機(jī)生成隨機(jī)個(gè)數(shù)的字母組合示例
在很多系統(tǒng)環(huán)境下大家都會(huì)用到字母組合各種編碼。下面為大家介紹下使用php隨機(jī)生成隨機(jī)個(gè)數(shù)的字母組合,感興趣的朋友可以了解下2014-01-01PHP常用日期加減計(jì)算方法實(shí)例小結(jié)
這篇文章主要介紹了PHP常用日期加減計(jì)算方法,結(jié)合實(shí)例形式總結(jié)分析了php日期計(jì)算常見(jiàn)的時(shí)區(qū)設(shè)置、date日期轉(zhuǎn)換、計(jì)算等相關(guān)操作技巧,需要的朋友可以參考下2018-07-07redis查看連接數(shù)及php模擬并發(fā)創(chuàng)建redis連接的方法
下面小編就為大家?guī)?lái)一篇redis查看連接數(shù)及php模擬并發(fā)創(chuàng)建redis連接的方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-12-12基于PHP安裝zip拓展,以及l(fā)ibzip安裝的問(wèn)題
下面小編就為大家分享一篇基于PHP安裝zip拓展,以及l(fā)ibzip安裝的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-03-03php中用foreach來(lái)操作數(shù)組的代碼
php中用foreach來(lái)操作數(shù)組的代碼,需要的朋友可以參考下。2011-07-07WampServer搭建php環(huán)境時(shí)遇到的問(wèn)題匯總
這篇文章主要介紹了WampServer搭建php環(huán)境時(shí)遇到的常見(jiàn)問(wèn)題的解決辦法匯總,以上所述就是本文的全部?jī)?nèi)容了。2015-07-07PHP設(shè)計(jì)模式之 策略模式Strategy詳解【對(duì)象行為型】
這篇文章主要介紹了PHP設(shè)計(jì)模式之 策略模式Strategy,結(jié)合實(shí)例形式詳細(xì)分析了PHP基于對(duì)象行為型的策略模式Strategy具體原理、實(shí)現(xiàn)技巧與相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2020-05-05