五月综合缴情婷婷六月,色94色欧美sute亚洲线路二,日韩制服国产精品一区,色噜噜一区二区三区,香港三级午夜理伦三级三

您現(xiàn)在的位置: 365建站網(wǎng) > 365文章 > PHP輸出緩存控制詳解及flush、ob_flush的區(qū)別

PHP輸出緩存控制詳解及flush、ob_flush的區(qū)別

文章來源:365jz.com     點(diǎn)擊數(shù):213    更新時(shí)間:2012-06-01 22:29   參與評(píng)論

<?php

for($i=0;$i<10;$i++) {

   echo $i.'<br />';

   flush();

   sleep(1);

}

?>

有了解過PHP緩存輸出控制函數(shù)的朋友肯定對(duì)上面這段代碼很熟悉,它想實(shí)現(xiàn)的效果是每個(gè)1秒輸出1個(gè)數(shù)字,完成全部輸出需要10秒,不過實(shí)際執(zhí)行中你會(huì)發(fā)現(xiàn)奇怪的現(xiàn)象,有些人或者有些時(shí)候它的表現(xiàn)如你所愿,而有些人或者有些時(shí)候卻是10秒后才會(huì)一次性輸出10個(gè)數(shù)字。我曾經(jīng)為此抓狂不已,有朋友留言說這個(gè)情況往往是因?yàn)镮E的緩存必須達(dá)到256個(gè)字符才會(huì)輸出,可實(shí)際上我之前也考慮到IE的情況,可依舊會(huì)有時(shí)靈時(shí)不靈的情況。今天仔細(xì)讀過手冊(cè)才明白,這些不可預(yù)料的現(xiàn)象是有它的理由的。

原來php.ini中有兩個(gè)關(guān)鍵參數(shù)會(huì)影響到php的緩存輸出控制:

參數(shù)1:output_buffering :on/off 或者整數(shù) 。設(shè)置為on時(shí),將在所有腳本中使用輸出緩存控制,不限制緩存的大小。而設(shè)置為整數(shù)時(shí),如output_buffering=4096,當(dāng)緩存數(shù)據(jù)達(dá)到4096字節(jié)時(shí)會(huì)自動(dòng)輸出刷新緩存。而這個(gè)參數(shù)的不同正是導(dǎo)致以上代碼在不同時(shí)候執(zhí)行結(jié)果不同的原因。當(dāng)output_buffering關(guān)閉時(shí),腳本所有的輸出(echo)都會(huì)即時(shí)發(fā)送到客戶端,執(zhí)行上面代碼時(shí)就是每秒輸出一個(gè)數(shù)字。而開啟output_buffering后,輸出內(nèi)容就會(huì)先緩存在服務(wù)端,直到腳本結(jié)束時(shí)才一起發(fā)送給客戶端。

參數(shù)2:implicit_flush:on/off。設(shè)定ON意味著,當(dāng)腳本有輸出時(shí),自動(dòng)立即發(fā)送到客戶端。相當(dāng)于在echo后自動(dòng)加flush()。

php緩存輸出控制的相關(guān)函數(shù):

ob_start()

第一個(gè)參數(shù):回調(diào)函數(shù),可選。在緩存輸出前可以對(duì)其進(jìn)行過濾或其他處理。最常見的用法是ob_start(‘ob_gzhandler’),即對(duì)緩存的數(shù)據(jù)進(jìn)行g(shù)zip壓縮后再發(fā)送給客戶端。
第二個(gè)參數(shù):緩存塊的大小,可選。如果被緩存的內(nèi)容達(dá)到或操作緩存塊的大小,緩存會(huì)自動(dòng)輸出。默認(rèn)值是0,指不限定大小,緩存到結(jié)束為止。還有個(gè)特殊值1,代表chunk_size=4096。
第三個(gè)參數(shù):是否擦除緩存,可選,默認(rèn)是true,如果設(shè)置為false,則在腳本執(zhí)行結(jié)束前,緩存都不會(huì)被清除。

可以使用ob_get_contents()以字符串形式獲取服務(wù)端緩存的數(shù)據(jù),使用ob_end_flush()則會(huì)輸出被緩存起來的數(shù)據(jù),并關(guān)閉緩存。
而使用ob_end_clean()則會(huì)靜默的清除服務(wù)端緩存的數(shù)據(jù),而不會(huì)有任何數(shù)據(jù)或其他行為。
服務(wù)端的緩存是堆疊起來的,也就是說你在開啟了ob_start()后,關(guān)閉之前,在其內(nèi)部還可以開啟另外一個(gè)緩存ob_start()。不過你也要?jiǎng)?wù)必保證關(guān)閉緩存的操作和開啟緩存的操作數(shù)量一樣多。
ob_start()可以指定一個(gè)回調(diào)函數(shù)來處理緩存數(shù)據(jù),如果一個(gè)ob_start()內(nèi)部嵌套了另一個(gè)ob_start(),我們假定,外層的ob_start(),編號(hào)是A,內(nèi)層的ob_start()編號(hào)是B,它們各自制定了一個(gè)回調(diào)函數(shù)分別是functionA和functionB,那么在緩存B中的數(shù)據(jù)輸出時(shí),它會(huì)先輩f(xié)uncitonB回調(diào)函數(shù)處理,再交給外層的functionA回調(diào)函數(shù)處理,之后才能輸出到客戶端。

另外,手冊(cè)說,對(duì)于某些web服務(wù)器,比如apache,在使用回調(diào)函數(shù)有可能會(huì)改變程序當(dāng)前的工作目錄,解決方法是在回調(diào)函數(shù)中自行手動(dòng)把工作目錄修改回來,用chdir函數(shù),這點(diǎn)似乎不常遇到,遇到的時(shí)候記得去查手冊(cè)吧。

flush()和ob_flush()

這兩個(gè)函數(shù)的使用怕是很多人最迷惑的一個(gè)問題,手冊(cè)上對(duì)兩個(gè)函數(shù)的解釋也語(yǔ)焉不詳,沒有明確的指出它們的區(qū)別,似乎二者的功能都是刷新輸出緩存。但在我們文章一開始的代碼中如果講fush()替換成ob_flush(),程序就再不能正確執(zhí)行了。顯然,它們是有區(qū)別的,否則也手冊(cè)中直接說明其中一個(gè)是另外一個(gè)函數(shù)的別名即可了,沒必要分別說明。那么它們的區(qū)別到底是什么呢?

反復(fù)研究了手冊(cè)的說明,參考了手冊(cè)中一些人的留言,自己琢磨應(yīng)該是這樣的:
在沒有開啟緩存時(shí),腳本輸出的內(nèi)容都在服務(wù)器端處于等待輸出的狀態(tài),flush()可以將等待輸出的內(nèi)容立即發(fā)送到客戶端。
開啟緩存后,腳本輸出的內(nèi)容存入了輸出緩存中,這時(shí)沒有處于等待輸出狀態(tài)的內(nèi)容,你直接使用flush()不會(huì)向客戶端發(fā)出任何內(nèi)容。而ob_flush()的作用就是將本來存在輸出緩存中的內(nèi)容取出來,設(shè)置為等待輸出狀態(tài),但不會(huì)直接發(fā)送到客戶端,這時(shí)你就需要先使用ob_flush()再使用flush(),客戶端才能立即獲得腳本的輸出。

也就是說本文開頭的腳本,可以根據(jù)緩存開啟與否,有如下幾種不同的寫法:

注:以下代碼都未考慮IE緩存必須大于256字節(jié)才輸出的問題,如在IE下測(cè)試,請(qǐng)?jiān)诖a開始加一句:“echo str_repeat(‘ ’,256)”

寫法1:
output_buffering = off
implicit_flush=off

<?php

for($i=0;$i<10;$i++) {

   echo $i.'<br />';

   flush();

   sleep(1);

}

?>

寫法2:
output_buffering = on
implicit_flush=off

<?php

for($i=0;$i<10;$i++) {

   echo $i.'<br />';

   ob_flush();

   flush();

   sleep(1);

}

?>

寫法3:
output_buffering = off
implicit_flush=off

<?php

ob_start();

for($i=0;$i<10;$i++) {

   echo $i.'<br />';

   ob_flush();

   flush();

   sleep(1);

}

?>

 

寫法4:
output_buffering = on
implicit_flush=off

<?php

ob_end_flush();

for($i=0;$i<10;$i++) {

   echo $i.'<br />';

   flush();

   sleep(1);

}

?>

寫法5:
output_buffering = on
implicit_flush=off

<?php

ob_end_clean();

for($i=0;$i<10;$i++) {

   echo $i.'<br />';

   flush();

   sleep(1);

}

?>

寫法6:
output_buffering = on;
implicit_flush=on

<?php

ob_end_clean();

//或者ob_end_flush();

for($i=0;$i<10;$i++) {

   echo $i.'<br />';

   sleep(1);

}

?>

寫法7:
output_buffering = on;
implicit_flush=on

<?php

ob_end_clean();

//或者ob_end_flush();

for($i=0;$i<10;$i++) {

   echo $i.'<br />';

   flush();

   sleep(1);

}

?>

寫法8:
output_buffering = off
implicit_flush=on

<?php

for($i=0;$i<10;$i++) {

   echo $i.'<br />';

   sleep(1);

}

?>

ob_end_flush():輸出當(dāng)前服務(wù)器端緩存的輸出數(shù)據(jù),并關(guān)閉緩存。

ob_end_clean():清空緩存內(nèi)容,并關(guān)閉緩存。

ob_get_flush():將當(dāng)前服務(wù)器端緩存的輸出數(shù)據(jù)以字符串形式返回,并關(guān)閉緩存

ob_get_contents():將緩存中保存的內(nèi)容以字符串形式返回,并保留緩存。

ob_get_length():返回緩存中數(shù)據(jù)的長(zhǎng)度。

ob_get_clean():獲取緩存中的數(shù)據(jù),請(qǐng)清空緩存,相當(dāng)于依次執(zhí)行ob_get_contents()和ob_end_clean()。

ob_implicit_flush():相當(dāng)于開啟php.ini中的implicit_flush參數(shù),立即發(fā)送腳本的輸出。

ob_gzhandler():使用gzip壓縮緩存數(shù)據(jù)。用于將文本數(shù)據(jù)壓縮后再發(fā)送到客戶端,可以極大減少數(shù)據(jù)傳輸所用的時(shí)間,對(duì)于提高網(wǎng)站瀏覽速度幫助很大。通常作為ob_start()的回調(diào)函數(shù)來使用。

ob_list_handlers():列出所有輸出使用的操作方法。
 

如對(duì)本文有疑問,請(qǐng)?zhí)峤坏浇涣髡搲瑥V大熱心網(wǎng)友會(huì)為你解答?。?點(diǎn)擊進(jìn)入論壇

發(fā)表評(píng)論 (213人查看0條評(píng)論)
請(qǐng)自覺遵守互聯(lián)網(wǎng)相關(guān)的政策法規(guī),嚴(yán)禁發(fā)布色情、暴力、反動(dòng)的言論。
昵稱:
最新評(píng)論
------分隔線----------------------------

其它欄目

· 建站教程
· 365學(xué)習(xí)

業(yè)務(wù)咨詢

· 技術(shù)支持
· 服務(wù)時(shí)間:9:00-18:00
365建站網(wǎng)二維碼

Powered by 365建站網(wǎng) RSS地圖 HTML地圖

copyright © 2013-2024 版權(quán)所有 鄂ICP備17013400號(hào)