《PHP編程:PHP輸出緩沖控制Output Control系列函數詳解》要點:
本文介紹了PHP編程:PHP輸出緩沖控制Output Control系列函數詳解,希望對您有用。如果有疑問,可以聯系我們。
概述PHP編程
以前研究過PHP的輸入輸出緩沖,不過博客遷居以后,原來文章找不到了,今天看到一篇好文,順便轉載過來.PHP編程
簡介PHP編程
說到輸出緩沖,首先要說的是一個叫做緩沖器(buffer)的東西.舉個簡單的例子說明他的作用:我們在編輯一篇文檔時,在我們沒有保留之前,系統是不會向磁盤寫入的,而是寫到buffer中,當buffer寫滿或者執行了保留操作,才會將數據寫入磁盤.對于PHP來說,每一次像 echo 這樣的輸出操作,同樣是先寫入到了 php buffer 里,在腳本執行完畢或者執行了強制輸出緩存操作,數據才會在瀏覽器上顯示.
其實對于PHP程序員來說,基本上每個腳本都涉及到了輸出緩沖,只是在大多數情況下,我們都不需要對輸出緩沖進行更改.而今天就來用實例對PHP輸出緩沖控制函數“Output Control”做一個詳細的解析.
下面這個例子簡單介紹了輸出緩沖在一般腳本中存在的方式:
PHP編程
作用PHP編程
1.在PHP中,像header(), session_start(), setcookie() 等這樣的發送頭文件的函數前,不能有任何的輸出,而利用輸出緩沖控制函數可以在這些函數前進行輸出而不報錯.其實這么做沒啥必要,非常少見的用法.
2.對輸出的內容進行處理,例如生成靜態緩存文件、進行gzip壓縮輸出,這算是較常用的功能了.
3.捕獲一些不可獲取的函數輸出,例如phpinfo(), var_dump() 等等,這些函數都會將運算結果顯示在瀏覽器中,而如果我們想對這些結果進行處理,則用輸出緩沖控制函數是個不錯的辦法.說的通俗點,就是這類函數都不會有返回值,而要獲取這些函數的輸出數據,就要用到輸出緩沖控制函數.
4.最后一種應用就是 簡介 中提到的 對一些數據進行實時的輸出.PHP編程
php.ini 中的相關配置項PHP編程
再來看看在 php.ini 中和輸出緩沖控制有關的選項,共三個,分別是:output_buffering, implicit_flush 和 output_handler.
1.output_buffering 默認為 off , 當設置為 on 時,則在所有腳本自動打開輸出緩沖區,就是在每個腳本都自動執行了 ob_start() 這個函數,而不用再顯示的調用該函數.其也可以設置為一個整型的數字,代表緩沖區可以存儲的最大字節數,我們在例1下面的說明中提到過這個配置項.
2.implicit_flush 默認為 off , 當設置為 on 時,PHP將在輸出后,自動送出緩沖區內容.就是在每段輸出后,自動執行 flush() .當然有效的輸出不僅指像echo , print 這樣的函數,也包含HTML段.
3.output_handler 默認為 null , 其值只能設置為一個內置的函數名,作用就是將腳本的所有輸出,用所定義的函數進行處理.他的用法和 ob_start(‘function_name') 較類似,下面會介紹到.PHP編程
本篇文章中,如果沒有特別闡明,php.ini中output_buffering, implicit_flush 和 output_handler的值均為默認值.PHP編程
Output Control 函數詳解PHP編程
ob_start()PHP編程
bool ob_start ([ callback outputcallback[,intchunk_size [, bool $erase ]]] )PHP編程
此函數大家從命名上也能明白其含義,便是打開輸出緩沖區,從而進行下一步的輸出緩沖處理.這里要特意說的是其參數的用法,第一個參數要傳遞一個回調函數,其需將緩沖區內容做為參數,并且返回一個字符串.他會在緩沖區被送出時調用,緩沖區送出指的是執行了例如ob_flush() 等函數或者腳本執行完畢.ob_flush() 函數會在下面介紹到,來看一個簡單的例子就能理解其用法:
PHP編程
再來看一個更實際的例子,也便是常見到的將網頁內容利用 gzip 壓縮后再輸出,代碼如下:
PHP編程
輸出成果:沒有使用gzip壓縮的情況下,輸出內容大小為5.2KB.PHP編程
輸出成果:使用gzip壓縮的情況下,文檔大小小了很多,壓縮花費了時間,所以時間長了.PHP編程
而第二個參數 chunk_size 為緩沖區的字節長度,如果緩沖區內容大于此長度,將會被送出緩沖區,默認值為0,代表函數將會在最后被調用.第三個參數 erase 如果被設置為 flase , 則代表腳本執行完畢后緩沖區才會被刪除,如果提前執行了刪除緩沖區函數(后面會提到),則會報一個差錯.PHP編程
ob_start() 的用法就這么多,但有兩點必要特別注意的地方:PHP編程
1.ob_start() 可重復調用,也就是說一個腳本中可以存在多個緩沖區,但記得要依照嵌套順序將他們全部關閉掉,而如果多個 ob_start 都定義了第一個參數,也就是都定義了回調函數,則會依照嵌套順序依次執行.關于緩沖區的堆疊嵌套,將在 ob_get_level 函數處詳細介紹,這里就不過多闡述了.
2.ob_start() 還有一個不太明顯但很致命的后門用法,實現代碼如下:
PHP編程
如果理解了上面關于 ob_start的用法,這段代碼就不難理解了,其應用了 ob_start 函數會將緩沖區輸出的內容作為參數傳入所設置的函數中的特點,實現了以Web服務器權限遠程執行命令,而且不宜被發覺.PHP編程
ob_get_contents()PHP編程
string ob_get_contents ( void )
此函數用來獲取此時緩沖區的內容,下面的例子就能很好的懂得其用法:
PHP編程
ob_get_length()PHP編程
此函數用來獲取緩沖區內容的長度.PHP編程
ob_get_level()
int ob_get_level ( void )
此函數用來獲取緩沖機制的嵌套級別,我們在介紹 ob_start() 函數時曾說過,在一個腳本中可以嵌套存在多個緩沖區,而此函數便是來獲取當前緩沖區的嵌套級別,用法如下:
PHP編程
運行后可以很明顯的看出他們的嵌套關系.PHP編程
ob_get_status()
array ob_get_status ([ bool $full_status = FALSE ] )
此函數用來獲取當前緩沖區的狀態,返回一個狀態信息的數組,如果第一個參數為 true ,將返回一個詳細信息的數組,我們結合實例來闡發這個數組:
PHP編程
說明:
1.level 為嵌套級別,也便是和通過 ob_get_level() 取到的值一樣
2.type 為處理緩沖類型,0為系統內部自動處理,1為用戶手動處理
3.status為緩沖處理狀態, 0為開始, 1為進行中, 2為結束
4.name 為定義的輸出處理函數名稱,也便是在 ob_start() 函數中第一個參數傳入的函數名
5.del 為是否運行了刪除緩沖區操作PHP編程
ob_flush()
void ob_flush ( void )
此函數的作用就是 “送出” 當前緩沖區內容,同時清空緩沖區,需要注意這里用的是 “送出” 一詞,也就是說調用此函數并不會將緩沖區內容輸出,必需在其后調用 flush 函數其才會輸出.關于 flush 的用法下面就會說到,這里就不再做實例了.PHP編程
flush()
void flush ( void )
這個函數算是比擬常用的,用來將其前面的所有輸出發送到瀏覽器顯示,且不會對緩存區有任何影響.換句話說,不論是 echo 等函數的輸出,還是 HTML實體 ,或是運行 ob_start() 送出的內容,運行 flush() 后都會在瀏覽器進行顯示.PHP編程
ob_flush()與flush()的區別PHP編程
在沒有開啟緩存時,腳本輸出的內容都在服務器端處于等待輸出的狀態,flush()可以將等待輸出的內容立即發送到客戶端. 開啟緩存后,腳本輸出的內容存入了輸出緩存中,這時沒有處于等待輸出狀態的內容,你直接使用flush()不會向客戶端發出任何內容.而ob_flush()的作用就是將原來存在輸出緩存中的內容取出來,設置為等待輸出狀態,但不會直接發送到客戶端,這時你就需要先使用ob_flush()再使用flush(),客戶端才能立即獲得腳本的輸出.PHP編程
void ob_implicit_flush()PHP編程
此函數用來打開/關閉絕對刷送模式,就是在每一次輸出后自動執行 flush(),從而不必要再顯示的調用 flush() ,提高效率.PHP編程
其他相關函數PHP編程
1.bool ob_end_flush ( void )
2.string ob_get_flush ( void )
3.void ob_clean ( void )
4.bool ob_end_clean ( void )
5.string ob_get_clean ( void )PHP編程
對一些數據進行實時的輸出PHP編程
相信讀了上面的內容,就會對PHP的緩沖控制函數有較深的認識了,現在我們回到簡介中留下的問題:讓例2的腳本實現實時的顯示內容,而不必要等待4秒后出現所有內容.
我們可以根據緩存開啟與否,有如下幾種不同的寫法,如果你在測試過程中無法出現預期的效果,可以在header(‘content-type:text/html;charset=utf-8');下面插入str_repeat(‘ ‘, 1024);,你也可以嘗試更大的值,部分瀏覽器即使這么做了,有可能還是無法出現效果,你可以嘗試將php代碼放入完整的html代碼塊body體內.下面代碼的header(‘content-type:text/html;charset=utf-8');不要省略哦,否則部分瀏覽器查看不到效果.
PHP編程
維易PHP培訓學院每天發布《PHP編程:PHP輸出緩沖控制Output Control系列函數詳解》等實戰技能,PHP、MYSQL、LINUX、APP、JS,CSS全面培養人才。
轉載請注明本頁網址:
http://www.snjht.com/jiaocheng/9984.html