buffer
buffer是一個內存地址空間,Linux系統默認大小通常爲4096(4kb),即一個內存頁。主要用於存儲速度不一樣步的設備或者優先級不一樣的設備之間傳辦理數據的區域。經過buffer,可使進程這間的相互等待變少。這裏說一個通俗一點的例子,你打開文本編輯器編輯一個文件的時候,你每輸入一個字符,操做系統並不會當即把這個字符直接寫入到磁盤,而是先寫入到buffer,當寫滿了一個buffer的時候,纔會把buffer中的數據寫入磁盤,固然當調用內核函數flush()的時候,強制要求把buffer中的髒數據寫回磁盤。
php
一樣的道理,當執行echo,print的時候,輸出並無當即經過tcp傳給客戶端瀏覽器顯示, 而是將數據寫入php buffer。php output_buffering機制,意味在tcp buffer以前,創建了一新的隊列,數據必須通過該隊列。當一個php buffer寫滿的時候,腳本進程會將php buffer中的輸出數據交給系統內核交由tcp傳給瀏覽器顯示。因此,數據會依次寫到這幾個地方:echo/print -> php buffer -> tcp buffer -> browser瀏覽器
php output_buffering
默認狀況下,php buffer是開啓的,並且該buffer默認值是4096,即4kb。你能夠經過在php.ini配置文件中找到output_buffering配置.當echo,print等輸出用戶數據的時候,輸出數據都會寫入到php output_buffering中,直到output_buffering寫滿,會將這些數據經過tcp傳送給瀏覽器顯示。你也能夠經過ob_start()手動激活php output_buffering機制,使得即使輸出超過了4kb數據,也不真的把數據交給tcp傳給瀏覽器,由於ob_start()將php buffer空間設置到了足夠大。只有直到腳本結束,或者調用ob_end_flush函數,纔會把數據發送給客戶端瀏覽器。緩存
1.當output_buffering=4096,而且輸出較少數據(少於一個buffer)
服務器
現象:不是每隔幾秒就會有間斷性輸出,而是直到響應結束,才能看一次性看到輸出,在等待服務器腳本處理結束以前,瀏覽器界面一直保持空白。這是由於,數據量過小,php output_buffering沒有寫滿。寫數據的順序,依次是echo->php buffer->tcp buffer->browserapp
2.當output_buffering=0,而且輸出較少數據(少於一個buffer)
less
現象:與剛纔顯示並不一致,禁用了php buffering機制以後,在瀏覽器能夠斷斷續續看到間斷性輸出,沒必要等到腳本執行完畢纔看到輸出。這是由於,數據沒有在php output_buffering中停留。寫數據的順序依次是echo->tcp buffer->browsertcp
3.當output_buffering=4096.,輸出數據大於一個buffer,不調用ob_start()
編輯器
現象:響應還沒結束(http鏈接沒有關閉),斷斷續續能夠看到間斷性輸出,瀏覽器界面不會一直保持空白。儘管啓用了php output_buffering機制,但依然會間斷性輸出,而不是一次性輸出,是由於output_buffering空間不夠用。每寫滿一個php buffering,數據就會發送到客戶端瀏覽器。函數
4.當output_buffering=4096, 輸出數據大於一個tcp buffer, 調用ob_start()
post
現象:直到服務端腳本處理完成,響應結束,纔看到完整輸,輸出間隔時間很短,以致你感覺不到停頓。在輸出以前,瀏覽器一直保持着空白界面,等待服務端數據。這是由於,php一旦調用了ob_start()函數,它會將php buffer擴展到足夠大,直到ob_end_flush函數調用或者腳本運行結速才發送php buffer中的數據到客戶端瀏覽器。
output buffering函數
1.ob_get_level
返回輸出緩衝機制的嵌套級別,能夠防止模板重複嵌套本身。
1.ob_start
激活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中的數據壓縮後再傳送給瀏覽器。
2.ob_get_contents
獲取一份php buffer中的數據拷貝。值得注意的是,你應該在ob_end_clean()函數調用以前調用該函數,不然ob_get_contents()返回一個空字符中。
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_clean()調用以後ob_get_contents()取到的是空字符串,同時瀏覽器也接收不到輸出,即沒有任何輸出。
慣用案例
經常在一些模板引擎和頁面文件緩存中看到ob_start()使用。下面溼CI中加載模板的程序代碼: