關於PHP 緩衝區php
ob_start: 打開輸出緩衝區,當緩衝區激活時,全部來自PHP程序的非頭文件信息均不會發送,而是保存在內部緩衝區。
ob_get_contents: 返回內部緩衝區的內容。
ob_get_clean: 返回內部緩衝區的內容,並關閉緩衝區,(至關於ob_get_contents() and ob_end_clean())。
ob_get_flush: 返回內部緩衝區的內容,並關閉緩衝區,再釋放內部緩衝區的內容。至關於ob_end_flush() 並返回內部緩衝區內容。
ob_get_lenght: 返回內部緩衝區的長度,若是緩衝區未被激活,該函數返回FALSE。
ob_clean: 刪除內部緩衝區的內容,但不關閉緩衝區,也就是說該語句以後的輸出內容將會繼續被添加至緩衝區。
ob_flush: 釋放內部緩衝區的內容,並刪除內部緩衝區的內容,但不關閉緩衝區。
flush: 刷新輸出緩衝,將ob_flush 釋放出來的內容,以及不在PHP 緩衝區的內容,所有輸出至瀏覽器。
ob_end_clean: 刪除內部緩衝區的內容,並關閉緩衝區。
ob_end_flush: 釋放內部緩衝區的內容,並關閉緩衝區。
(這裏只要帶flush 都會輸出)
ob_gzhandler: ob_start回調函數,用gzip 壓縮緩衝區的內容。
ob_implicit_flush: 打開或關閉絕對刷新,默認爲關閉。所謂絕對刷新,當有輸出語句,好比說echo被執行時,便把輸出直接發送到瀏覽器,而再也不須要調用flush()或等到腳本結束時才輸出。
注意事項:
一些Web服務器的output_buffering默認是4069字符或者更大,即輸出內容必須達到4069字符服務器纔會flush刷新輸出緩衝,爲 了確保flush有效,最好在ob_flush()函數前有如下語句:
print str_repeat(「 」, 4096); //以確保到達output_buffering值。
ob_* 系列函數是操做PHP自己的輸出緩衝區,因此,ob_flush只刷新PHP自身的緩衝區。而flush是刷新apache的緩衝區。因此,正確使用倆者的順序是:先ob_flush,而後flush。ob_flush是把數據從PHP的緩衝中釋放出來,flush是把緩衝內/外的數據所有發送到瀏覽器。
不要誤認爲用了ob_start()後,腳本的echo/print等輸出就永遠不會顯示在瀏覽器上了。由於PHP腳本運行結束後,會自動刷新緩衝區並輸出內容。
要先ob_start()再 flash不然報錯 Message: ob_flush() [ref.outcontrol]: failed to flush buffer. No buffer to flush.
咱們在說說ob_start的用法
ob_start([string output_callback]):這裏但是設置一個回調函數,打開緩衝區以後,全部的輸出信息再也不直接發送掉瀏覽器,而是保存在輸出緩衝區裏面,能夠用這個回調函數用於處理輸出結果的信息.
好比:
function test($str){
return str_replace('php100','haha',$str);
}
ob_start('test');
echo 'hello php100';
ob_end_flush();
在上面的例子中,使用 echo() 的輸出內容將會保存在輸出緩衝區中,直到調用了 ob_end_flush()或者腳本運行終止, 而後輸出信息由自定義的處理函數進行處理(替換裏面的字符串)並返回結果。
buffer ---- flush()
buffer是一個內存地址空間,Linux系統默認大小通常爲4096(1kb),即一 個內存頁。主要用於存儲速度不一樣步的設備或者優先級不一樣的 設備之間傳辦理數據的區域。經過buffer,可使進程這間的相互等待變少。這裏說一個通俗一點的例子,你打開文本編輯器編輯一個文件的時候,你每輸入 一個字符,操做系統並不會當即把這個字符直接寫入到磁盤,而是先寫入到buffer,當寫滿了一個buffer的時候,纔會把buffer中的數據寫入磁 盤,固然當調用內核函數flush()的時候,強制要求把buffer中的髒數據寫回磁盤。
一樣的道理,當執行echo,print的時 候,輸出並無當即經過tcp傳給客戶端瀏覽器顯示, 而是將數據寫入php buffer。php output_buffering機制,意味在tcp buffer以前,創建了一新的隊列,數據必須通過該隊列。當一個php buffer寫滿的時候,腳本進程會將php buffer中的輸出數據交給系統內核交由tcp傳給瀏覽器顯示。因此,數據會依次寫到這幾個地方echo/pring -> php buffer -> tcp buffer -> browser
php output_buffering --- ob_flush()
默 認狀況下,php buffer是開啓的,並且該buffer默認值是4096,即1kb。你能夠經過在php.ini配置文件中找到output_buffering配 置.當echo,print等輸出用戶數據的時候,輸出數據都會寫入到php output_buffering中,直到output_buffering寫滿,會將這些數據經過tcp傳送給瀏覽器顯示。你也能夠經過 ob_start()手動激活php output_buffering機制,使得即使輸出超過了1kb數據,也不真的把數據交給tcp傳給瀏覽器,由於ob_start()將php buffer空間設置到了足夠大 。只有直到腳本結束,或者調用ob_end_flush函數,纔會把數據發送給客戶端瀏覽器。
這 兩個函數的使用怕是不少人最迷惑的一個問題,手冊上對兩個函數的解釋也語焉不詳,沒有明確的指出它們的區別,彷佛兩者的功能都是刷新輸出緩存。但在咱們 文章一開始的代碼中若是講fush()替換成ob_flush(),程序就再不能正確執行了。顯然,它們是有區別的,不然也手冊中直接說明其中一個是另外 一個函數的別名便可了,不必分別說明。那麼它們的區別究竟是什麼呢?
在沒有開啓緩存時,腳本輸出的內容都在服務器端處於等待輸出的狀態 ,flush()能夠將等待輸出的內容當即發送到客戶端。
開 啓緩存後,腳本輸出的內容存入了輸出緩存中 ,這時沒有處於等待輸出狀態的內容,你直接使用flush()不會向客戶端發出任何內容。而 ob_flush()的做用就是將原本存在輸出緩存中的內容取出來,設置爲等待輸出狀態,但不會直接發送到客戶端 ,這時你就須要先使用 ob_flush()再使用flush(),客戶端才能當即得到腳本的輸出。
一. flush和ob_flush的正確順序,正確應是,先ob_flush再flush,以下:
ob_flush();
flush();
若是Web服務器的操做系統是windows系統,那順序顛倒或者不使用ob_flush()也不會出現問題。[有待求證 ] 可是在Linux系統上就沒法刷新輸出緩衝。
output buffering函數
1.bool ob_start ([ callback $output_callback [, int $chunk_size [, bool $erase ]]] )
激活output_buffering機制。一旦激活,腳本輸出再也不直接出給瀏覽器,而是先暫時寫入php buffer內存區域。
php默認開啓output_buffering機制,只不過,經過調用ob_start()函數據output_buffering值擴展到足夠 大 。也能夠指定$chunk_size來指定output_buffering的值。$chunk_size默認值是0,表示直到腳本運行結束,php buffer中的數據纔會發送到瀏覽器。若是你設置了$chunk_size的大小 ,則表示只要buffer中數據長度達到了該值,就會將buffer中 的數據發送給瀏覽器。
固然,你能夠經過指定$ouput_callback,來處理buffer中的數據。好比函數ob_gzhandler,將buffer中的數據壓縮後再傳送給瀏覽器。
第三個參數:是否擦除緩存,可選,默認是true,若是設置爲false,則在腳本執行結束前,緩存都不會被清除。
2.ob_get_contents
獲取一份php buffer中的數據拷貝。值得注意的是,你應該在ob_end_clean()函數調用前調用該函數,不然ob_get_contents()返回一個空字符中。
可使用ob_get_contents()以字符串形式獲取服務端緩存的數據,
使用ob_end_flush()則會輸出被緩存起來的數據,並關閉緩存。
而使用ob_end_clean()則會靜默的清除服務端緩存的數據,而不會有任何數據或其餘行爲。
服務端的緩存是堆疊起來的,也就是說你在開啓了ob_start()後,關閉以前,在其內部還 能夠開啓另一個緩存ob_start()。
不過你也要務必保證關閉緩存的操做和開啓緩存的操做數量同樣多。
ob_start() 能夠指定一個回調函數來處理緩存數據,若是一個ob_start()內部嵌套了另外一個ob_start(),咱們假定,外層的ob_start(),編號 是A,內層的ob_start()編號是B,它們各自制定了一個回調函數分別是functionA和functionB,那麼在緩存B中的數據輸出時,它 會先輩funcitonB回調函數處理,再交給外層的functionA回調函數處理,以後才能輸出到客戶端。
另外,手冊說,對於某些web服務器,好比apache,在使用回調函數有可能會改變程序當前的工做目錄,解決方法是在回調函數中自行手動把工做目錄修改回來,用chdir函數,這點彷佛不常遇到,遇到的時候記得去查手冊吧。
3.ob_end_flush與ob_end_clean
這 二個函數有點類似,都會關閉ouptu_buffering機制。但不一樣的是,ob_end_flush只是把php buffer中的數據衝(flush/send)到客戶端瀏覽器,而ob_clean_clean將php bufeer中的數據清空(erase),但不發送給客戶端瀏覽器。
ob_end_flush調用以前 ,php buffer中的數據依然存在,ob_get_contents()依然能夠獲取php buffer中的數據拷貝。
而ob_end_flush()調用以後 ob_get_contents()取到的是空字符串,同時瀏覽器也接收不到輸出,即 沒有任何輸出。
可使用ob_get_contents()以字符串形式獲取服務端緩存的數據,使用ob_end_flush()則會輸出被緩存起來的數據,並關閉緩存。
而使用ob_end_clean()則會靜默的清除服務端緩存的數據,而不會有任何數據或其餘行爲。web