">

首頁  >  文章  >  後端開發  >  剖析 PHP 中的輸出緩衝

剖析 PHP 中的輸出緩衝

WBOY
WBOY原創
2016-07-29 08:35:511012瀏覽

我們先來看一段程式碼:
    〈?php
    for ($i=10; $i〉0; $i--)
    { ;
     sleep(1);
    }
    ?〉
    依照php手冊中的說法,該函數將目前的所有輸出傳送到使用者的瀏覽器。
    上面的這段程式碼,而應該隔一秒輸出一次$i。但是實際中卻不一定是這樣。有可能是等了10秒鐘後,所有的輸出同時呈現。
    好,我們來改變這段程式碼,改成
    〈?php
    ob_end_clean();//修改部分 -)
    {
     echo $i;
     flush();
       嘿,加了這句話ob_end_clean(); ,居然就OK了。實際上,我們把ob_end_clean()換成ob_end_flush()也一樣OK。
    我再來改一改。
    〈?php
    for ($i=10; $i〉0; $i--)
    {  $i--)
    {  $. 🎜 >     flush();
     sleep(1);
    }
    ?〉
  )這是為什麼呢?
    別急,我們來看看php.ini。
    打開php.ini,搜尋output_buffering,我們會看到類似這樣的設定 output_buffering = 4096。就像它的名字output_buffering一樣,這個設定的作用就是把輸出緩衝一下,緩衝大小為4096bytes.
    在我們的第一段程式碼裡,之所以沒有按預期的輸出,正是因為這個output_buffering把那些輸出都緩衝了。沒達到4096bytes或腳本結束,輸出是不會被送出去的。
    而第二段程式碼中的ob_end_clean()和ob_end_flush()的作用,就是終止緩衝。這樣就不用等到有4096bytes的緩衝之後才被送出去了。
    第三段程式碼中,用了一句ob_flush(),它的作用就是把緩衝的資料送出去,但是並不會終止緩衝,所以它必須在每次flush()前使用。
    如果不想使用ob_end_clean(),ob_end_flush()和ob_flush(),我們就必須把php.ini裡的output_buffering設得夠小,例如設為0。要注意的是,如果你打算在腳本中使用ini_set(”output_buffering”,”0″)來設置,那麼請停下來吧,這種方法是不行的。因為在腳本一開始的時候,緩衝設定就已經被載入,然後緩衝就開始了。
    可能你會問了,既然ob_flush()是把緩衝的資料送出去,那麼為什麼還需要用flush()???直接用下面這段程式碼不行嗎? ?
    〈?php
    for ($i=10; $i〉0; $i--)
    {      sleep(1 );
    }
    ?〉
    請注意ob_flush()與flush()的差異。前者是把資料從PHP的緩衝中釋放出來,後者是把不在緩衝中的或是被釋放出來的資料傳送到瀏覽器。所以當緩衝存在的時候,我們必須ob_flush()和flush()同時使用。
    那是不是flush()在這裡就是不可缺少的呢?不是的,我們還有另一種方法,使得當有資料輸出的時候,馬上就被送到瀏覽器。下面這兩段程式碼就是不需要使用flush()了。(當你把output_buffering設為0的時候,連ob_flush()和ob_end_clean()都不需要了)
    〈?php
    ob_implicit_flush(true)
    ob_implicit_flush(true)
; 〉0; $i--)
    {
     echo $i;
     ob_flush();     〈?php
    ob_end_clean();
    ob_implicit_flush(true);
    for ($i=10) $ ;
     sleep( 1);
    }
    ?〉
    請留意看上面的ob_implicit_flush(true),這個函數強制每當有輸出的時候,即刻把輸出送到上面的ob_implicit_flush(true),這個函數強制每當有輸出的時候,即刻把輸出送到上面。這樣就不需要每次輸出(echo)後,都用flush()來傳送到瀏覽器了。
    以上所訴可能在某些瀏覽器中不成立。因為瀏覽器也有自己的規則。我是用Firefox1.5,IE6,opera8.5來測試的。其中opera不能正常輸出,因為它有一個規則,就是不遇到一個HTML標籤,就絕對不輸出,除非到腳本結束。而FireFox和IE還算比較正常的。
    最後附上一段非常有趣的程式碼,作者為PuTTYshell。在一個腳本週期裡,每次輸出,都會把前一次的輸出覆蓋掉。
    以下程式碼只在firefox下可用,其他瀏覽器並不支援multipart/x-mixed-replace的Content-Type.
    〈?php
   -replace;boundary=endofsection');
      print 「n--endofsectionn「;
      $pm $i = 0; $i 〈10; $i ++ ){
         sleep(1);
       print 「Part $it「.$pmt [$i % 4];
         print 「--endofsectionn「;
          }
      print 「Content-type: text/plainnn「;
      print 「The endn「;
      print 「--endofsection--n「;
    ?〉 
以上就介紹了 剖析 PHP 中的輸出緩衝,包括了方面的內容,希望對PHP教程有興趣的朋友有所幫助。


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn