PHP 瀏覽器即時輸出運動進度 僅對 IE有效 FIREFOX、CHROME未解決

來源:互聯網
上載者:User

nginx 裡面在php 的section 加入

fastcgi_buffer_size 1k;
fastcgi_buffers 128 1k; # up to 1k + 128 * 1k
fastcgi_max_temp_file_size 0;
proxy_buffering off
gzip off;


<?php for ($i=10; $i>0; $i--) {     echo $i;     flush();     sleep(1); } ?>

按照php手冊裡的說法

    該函數將當前為止程式的所有輸出發送到使用者的瀏覽器。

上面的這段代碼,應該隔一秒鐘輸出一次$i。但是實際中卻不一定是這樣。有可能是等了10秒鐘後,所有的輸出同時呈現出來。

好,我們來改一下這段代碼,改成

<?php ob_end_clean();//修改部分

echo str_pad(" ", 256); for ($i=10; $i>0; $i--) {     echo $i;     flush();     sleep(1); } ?>

嘿,加了這一句ob_end_clean();,居然就OK了。實際上,我們把ob_end_clean()換成ob_end_flush()也一樣OK。

注意:IE需要接受到256個位元組之後才開始顯示。

所以,我們需要在之前加上:echo str_pad(" ", 256);


我再來改一改。

<?php

echo str_pad(" ", 256); for ($i=10; $i>0; $i--) {     echo $i;     ob_flush();//修改部分     flush();     sleep(1); } ?>

運行一下,是不是發現$i也隔一秒輸出一次了?這是為什麼呢?

別急,我們來看看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

echo str_pad(" ", 256); for ($i=10; $i>0; $i--) {     echo $i;     ob_flush();     sleep(1); } ?>

請注意ob_flush()和flush()的區別。前者是把資料從PHP的緩衝中釋放出來,後者是把不在緩衝中的或者說是被釋放出來的資料發送到瀏覽器。所以當緩衝存在的時候,我們必須ob_flush()和flush()同時使用。

那 是不是flush()在這裡就是不可缺少的呢?不是的,我們還有另外一種方法,使得當有資料輸出的時候,馬上被發送到瀏覽器。下面這兩段代碼就是不需要使 用flush()了。(當你把output_buffering設為0的時候,連ob_flush()和ob_end_clean()都不需要了)

<?php

ob_implicit_flush(true);

echo str_pad(" ", 256); for ($i=10; $i>0; $i--) {     echo $i;     ob_flush();     sleep(1); } ?>

<?php ob_end_clean(); ob_implicit_flush(true);

echo str_pad(" ", 256); for ($i=10; $i>0; $i--) {     echo $i;     sleep(1); } ?>

請注意看上面的ob_implicit_flush(true),這個函數強制每當有輸出的時候,即刻把輸出發送到瀏覽器。這樣就不需要每次輸出(echo)後,都用flush()來發送到瀏覽器了。

以 上所訴可能在某些瀏覽器中不成立。因為瀏覽器也有自己的規則。我是用Firefox1.5,IE6,opera8.5來測試的。其中opera就不能正常 輸出,因為它有一個規則,就是不遇到一個HTML標籤,就絕對不輸出,除非到指令碼結束。而FireFox和IE還算比較正常的。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.