首頁  >  文章  >  後端開發  >  php 緩衝區

php 緩衝區

不言
不言原創
2018-05-15 17:46:433133瀏覽

這篇文章給介紹的是PHP緩衝區這一部分的知識,現在分享給大家,也給有需要幫助的朋友一個參考,大家一起來看一看吧

什麼是緩衝區?
簡單而言,緩衝區的作用就是,把輸入或輸出的內容先放進記憶體,而不顯示或讀取.至於為什麼要有緩衝區,這是一個很廣泛的問題,

其實緩衝區最本質的作用就是,協調高速CPU和相對緩慢的IO設備(磁碟等)的運作。

想要了解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;

#1

2


#echo "this is test ";

header("LOCATION http://www.baidu.com"#);

#


出現這個錯誤的原因是, 在header之前已經輸出了某些數據,而輸出這些數據的同時, apache將會同時發送一個響應狀態到瀏覽器上(既然有輸出,即這個請求是有效的),而其後你又再次使用header函數
發送http頭,則會返回這個錯誤,錯誤的意思是:HTTP頭已經發送出去了,你不能對他再做修改.
為什麼使用緩衝區可以避免這個錯誤呢?
因為header函數是不受緩衝區影響的,當一碰到header函數的時候,PHP馬上執行apache發送這一個http頭都瀏覽器.
而輸出的資料PHP開啟輸出緩衝區後, 這些資料將會存放在緩衝區,等待輸出.這樣就可以避免了之前所發生的錯誤.
2.透過PHP寫檔案下載程式的時候.
為了讓文件下載更安全,同時提高更多的可控性,很多朋友都喜歡用PHP寫文件下載頁面.其原理很簡單,就是通過fwrite把文件內容讀出並顯示,然後通過header來發送HTTP頭,讓瀏覽器知道這是一個附件,這樣
就可以達到提供下載的效果.
如果用上面的辦法提供下載頁面,會碰到一個效率問題,如果一個文件很大,假設為100M ,那麼在不開啟緩衝區輸出的情況下,必須要把100M資料全部讀出,然後一次返回到頁面上,如果這樣做,用戶將會在所有資料讀完
之後才會得到回應,降低使用者體驗感.
如果開啟了輸出緩衝區,當PHP程式讀完檔案的某一段,然後馬上輸出到apache,然後讓apache馬上回到瀏覽器,這樣就可以減少使用者等待時間.那後面的資料怎麼辦呢?我們可以寫一個while循環,一直一段一段地讀取文件
每讀一段,就馬上輸出,直到把文件全部輸出為止,這樣瀏覽器就可以持續地接受到數據,而不必等到所有文件讀取完畢.

另外,該做法還解決了另外一個很嚴重的問題.例如一個文件是100M,如果不開啟緩衝區的情況下,則需要把100M文件全部讀入內存,然後再輸出.但是,如果PHP程式做了內存限制呢?為了保證伺服器的穩定,管理員通常會把PHP的執行
內存設一個限制(通過php.ini總的memory_limit, 其默認值是8M), 也就是每個PHP程式使用的記憶體不能使用超過這個值的記憶體. 假設該值為8M,而要讀入的檔案是100M,根本就沒有足夠的記憶體來讀入該檔案.這個時候,我們就需要用到上面的
辦法來解決這個問題,每次只讀某一段,這樣就可以避免了內存的限制
3.靜態文件緩存
現在很多公司有這麼一個需求, 就是某一個頁面在第一次造訪的時候,會執行PHP,然後把顯示的內容返回到瀏覽器,同時需要把這次顯示的內容保存到伺服器上,這樣下次訪問的時候,就直接把保存在伺服器上的檔案直接顯示,而不需要透過PHP來做操作
這就是所謂的」靜態頁面快取」.那怎麼樣才能做到把內容回傳到瀏覽器的同時把資料儲存到伺服器上呢?這就要用到輸出緩衝區了.

#


與輸出緩衝區有關的配置

在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才會刷新,所以為了保證內容的資料,可以添加以下程式碼,保證內容長度

#1

##2

##3

#4

5

6


#ob_start();

echo

'aaa';

#$string

= ob_get_contents();

file_put_contents

('a.html', $string);

ob_flush();

#flush

();

#1

2

3

4

5


#<?php

 

#echo 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緩衝區? ######

以上是php 緩衝區的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn