這兩個函數的使用怕是很多人最迷惑的一個問題,手冊上對兩個函數的解釋也語焉不詳,沒有明確的指出它們的區別,似乎二者的功能都是刷新輸出緩存。但在我們文章一開始的代碼中如果講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()則會靜默的清除服務端緩存的數據,而不會有任何數據或其他行為。
服務端的緩存是堆疊起來的,也就是說你在開啟了ob_start()後,關閉之前,在其內部還可以開啟另外一個緩存ob_start()。不過你也要務必保證關閉緩存的操作和開啟緩存的操作數量一樣多。
ob_start() 可以指定一個回調函數來處理緩存數據,如果一個ob_start()內部嵌套了另一個ob_start(),我們假定,外層的ob_start(),編號是A,內層的ob_start()編號是B,它們各自制定了一個回調函數分別是functionA和functionB,那麼在緩存B中的數據輸出時,它會先輩funcitonB回調函數處理,再交給外層的functionA回調函數處理,之後才能輸出到客戶端。
另外,手冊說,對於某些web服務器,比如apache,在使用回調函數有可能會改變程序當前的工作目錄,解決方法是在回調函數中自行手動把工作目錄修改回來,用chdir函數,這點似乎不常遇到,遇到的時候記得去查手冊吧。