什麼是緩衝區?
簡單而言,緩衝區的作用就是,把輸入或者輸出的內容先放進記憶體,而不顯示或者讀取.至於為什麼要有緩衝區,這是乙個很廣泛的問題,如果有興趣,可以在網上找下資料.
其實緩衝區最本質的作用就是,協調高速cpu和相對緩慢的io裝置(磁碟等)的運作.
php在執行的時候,在什麼地方有用到緩衝區?
想要了解php的緩衝區,就要知道執行php的時候,緩衝區被設定到了什麼地方.
當執行php的時候,如果碰到了echo print_r之類的會輸出資料的**,php就會將要輸出的資料放到php自身的緩衝區,等待輸出.
當php自身的緩衝區接到指令,指示要輸出緩衝區的內容時,將會把緩衝區內的資料輸出到apache上, apache接受到php輸出的資料,然後再把該資料存在到apache自身的緩衝區內,等到輸出
當apache接受到指令,只是要輸出緩衝區的內容時, 將會把緩衝區的內容輸出,返回到瀏覽器.
由此可見,php要輸出資料的時候,將會經過兩個緩衝區(先是自身的,然後是apache的),再返回到瀏覽器.
緩衝區在php中起到什麼作用?
1.最常見的就是在使用header函式之前,就已經輸出了某些資料,這樣會導致某些錯誤,例如 cannot modify header information – headers already sent by;
echo "this is test";
header("location ");
出現這個錯誤的原因是, 在header之前已經輸出了某些資料,而輸出這些資料的同時, apache將會同時傳送乙個響應狀態到瀏覽器上(既然有輸出,即這個請求是有效的),而其後你又再次使用header函式
傳送http頭,則會返回這個錯誤,錯誤的意思是:http頭已經傳送出去了,你不能對他再做修改.
為什麼使用緩衝區可以避免這個錯誤呢?
另外,該做法還解決了另外乙個很嚴重的問題.例如乙個檔案是100m,如果不開啟緩衝區的情況下,則需要把100m檔案全部讀入記憶體,然後再輸出.但是,如果php程式做了記憶體限制呢?為了保證伺服器的穩定,管理員通常會把php的執行
記憶體設乙個限制(通過php.ini總的memory_limit, 其預設值是8m), 也就是每個php程式使用的記憶體不能使用超過這個值的記憶體. 假設該值為8m,而要讀入的檔案是100m,根本就沒有足夠的記憶體來讀入該檔案.這個時候,我們就需要用到上面的
辦法來解決這個問題,每次唯讀某一段,這樣就可以避免了記憶體的限制
3.靜態檔案快取
現在很多公司有這麼乙個需求, 就是某乙個頁面在第一次訪問的時候,會執行php,然後把顯示的內容返回到瀏覽器,同時需要把這次顯示的內容儲存到伺服器上,這樣下次訪問的時候,就直接把儲存在伺服器上的檔案直接顯示,而不需要通過php來做操作
這就是所謂的」靜態頁面快取」.那怎麼樣才能做到把內容返回到瀏覽器的同時把資料儲存到伺服器上呢?這就要用到輸出緩衝區了.
ob_start();echo 'aaa';
$string = ob_get_contents();
file_put_contents('a.html', $string);
ob_flush();
flush();
與輸出緩衝區有關的配置
在php.ini中,有兩個跟緩衝區緊密相關的配置項
1.output_buffering
該配置直接影響的是php本身的緩衝區,有3種配置引數.on/off/xk(x為某個整型數值);
on - 開啟緩衝區
off - 關閉緩衝區
256k - 開啟緩衝區,而且當緩衝區的內容超過256k的時候,自動重新整理緩衝區(把資料傳送到apache);
2.implicit_flush
該配置直接影響apache的緩衝區,有2種配置引數. on/off
on - 自動重新整理apache緩衝區,也就是,當php傳送資料到apache的緩衝區的時候,不需要等待其他指令,直接就把輸出返回到瀏覽器
off - 不自動重新整理apache緩衝區,接受到資料後,等待重新整理指令
與緩衝區有關的函式
1.ob_implicit_flush
作用和implicit_flush一樣,是否自動重新整理apache的緩衝區
2.flush
作用是傳送指令到apache,讓apache重新整理自身的輸出緩衝區.
3.ob_start
開啟輸出緩衝區,無論php.ini的檔案如何配置,如果使用該函式,即使output_buffering設定成off,也會開啟輸出緩衝區
ob_start函式還接受乙個引數,該引數是乙個函式的**,意思是,在輸入緩衝區內容之前,需要使用呼叫傳遞進來的引數把緩衝區的內容處理一次,再放入緩衝區內
4.ob_flush
指示php本身重新整理自身的緩衝區,把資料傳送到apache
5.ob_clean
清除php緩衝區裡面的內容
6.ob_end_clean
清除php緩衝區內的內容,並且關閉輸出緩衝區
7.ob_end_flush
把php自身的緩衝區裡的內容傳送到apache,並把清除自身緩衝區內的內容
8.ob_get_clean
獲取緩衝區的內容之後,清除緩衝區.
9.ob_get_contents
獲取輸出緩衝區裡的內容
10.ob_get_flush
獲取緩衝區裡的內容,並且把這些內容傳送到apache
11.ob_get_length
獲取緩衝區裡內容的長度
12.ob_list_handlers
獲取執行ob_start時,所**的函式名稱, 例如:
ob_start(『ob_gzhandler』);
print_r(ob_list_handlers);
將列印出ob_gzhandler;
13.ob_gzhandler
該函式的作用是作為ob_start的**引數, 在緩衝區重新整理之前,會呼叫該函式對資料進行到底gzip或者deflate壓縮.這個函式需要zlib擴充套件的支援.
1.ob_flush和flush的次序關係.上面的分析可以看出,ob_flush是和php自身相關的,而flush操作的是apache的緩衝區,所有我們在使用這兩個函式的時候,需要先執行ob_flush,
再執行flush,因為我們需要先把資料從php上傳送到apache,然後再由apache返回到瀏覽器.如果php還沒有把資料重新整理到apache,就呼叫了flush,則apache無任何資料返回到瀏覽器.
2.有的瀏覽器,如果接受到的字元太少,則不會把資料顯示出來,例如老版的ie(必須要大於256k才顯示).這樣就會造成乙個疑問, 明明在php和apache都進行了重新整理緩衝區的操作,但是瀏覽器就是沒有出現自己想要的資料,也許就是這個原因造成的.所以才測試的時候,可以在輸出資料的後面加上多個空格,以填滿資料,確定不會瀏覽器造成這類詭異的問題.
3.有些webserver,他自身的輸出緩衝區會有一些限制,比如nginx,他有乙個配置fastcgi_buffer_size 4k, 就是是表明,當自身的輸出緩衝區的內容達到4k才會重新整理,所以為了保證內容的資料,可以新增以下**,保證內容長度
<?phpecho str_repeat(" ",4096);
?>
4.在apache中,如果你開啟了mod_gzip的壓縮模組,這樣可能會導致你的flush函式重新整理不成功,其原因是,mod_gzip有自己的輸出緩衝區,當php執行了flush函式,指示apache重新整理輸出緩衝區,但是內容需要壓縮,apache就把內容輸出到自身的mod_gzip模組,mod_gzip也有自身的輸出 緩衝區,他也不會馬上輸出,所以造成了內容不能馬上輸出.為了改善這個情況,可以關閉mod_gzip模組,或者在httpd.conf增加以下內容,以禁止壓縮
setenv no-gzip dont-vary
php 緩衝區,PHP的輸出緩衝區
1 什麼是緩衝區?緩衝區的作用是把輸入或者輸出的內容先放進記憶體,而不顯示或者讀取,最本質的作用就是協調高速cpu和相對緩慢的io裝置 磁碟等 的運作。2 php在執行的時候,在什麼地方有用到緩衝區?當執行php的時候,如果碰到了echo print r之類的會輸出資料的 php就會將要輸出的資料放...
PHP的輸出緩衝區
在php中有乙個名為 輸出緩衝區 ob 的東西。php的輸出流包含很多位元組,通常是echo語句或者printf 函式輸出的。這些東西的資料需要用到輸出緩衝區。一般php的輸出就是按照上面這張圖在各個緩衝區間流轉,但是cli模式下有些特殊。在cli模式下ini的配置中 output buffer 選...
輸出緩衝區
輸出緩衝區 printf 輸出緩衝區 顯示器 printf函式列印的內容會先送入輸出緩衝區,輸出緩衝區將資料送到顯示器我們才能看見。什麼時候輸入緩衝區會將資料送到顯示器 什麼時候輸出緩衝區會清空 1 當輸出乙個換行符時 2 當輸入時,先清空輸出緩衝區 3 輸出緩衝區滿時 4 當主動呼叫fflush ...