Press "Enter" to skip to content

深入理解ob_flush和flush的区别

ob_flush/flush在手册中的描述, 都是刷新输出缓冲区, 并且还需要配套使用, 所以会导致很多人迷惑...
其实, 他们俩的操作对象不同, 有些情况下, flush根本不做什么事情..
ob_*系列函数, 是操作PHP本身的输出缓冲区.
所以, ob_flush是刷新PHP自身的缓冲区.
而flush, 严格来讲, 这个只有在PHP做为apache的Module(handler或者filter)安装的时候, 才有实际作用. 它是刷新WebServer(可以认为特指apache)的缓冲区.
在apache module的sapi下, flush会通过调用sapi_module的flush成员函数指针, 间接的调用apache的api: ap_rflush刷新apache的输出缓冲区, 当然手册中也说了, 有一些apache的其他模块, 可能会改变这个动作的结果..

有些Apache的模块,比如mod_gzip,可能自己进行输出缓存,
这将导致flush()函数产生的结果不会立即被发送到客户端浏览器。
甚至浏览器也会在显示之前,缓存接收到的内容。例如 Netscape
浏览器会在接受到换行或 html 标记的开头之前缓存内容,并且在
接受到 </table> 标记之前,不会显示出整个表格。
一些版本的 Microsoft Internet Explorer 只有当接受到的256个
字节以后才开始显示该页面,所以必须发送一些额外的空格来让这
些浏览器显示页面内容。

所以, 正确使用俩者的顺序是. 先ob_flush, 然后flush,
当然, 在其他sapi下, 不调用flush也可以, 只不过为了保证你代码的可移植性, 建议配套使用.

21 Comments

  1. Hotmail Login
    Hotmail Login March 20, 2018

    It is a good and amazing article. Your information is very useful for me and for others. thank you so much.

  2. Zithromax
    Zithromax October 26, 2016

    kv9152 Hello, sound situate! Gratefulness you as your period! gl8896xa8057uh2788

  3. Gordon
    Gordon April 21, 2016

    From next monday i’m gonna lose weight. Summer is comming guys!
    Who starts with me? I found a good method in google and want
    to give it a try, simply search in g00gle: fitMarikka advices

  4. MadieCBordwine
    MadieCBordwine June 4, 2015

    Greetings I am so glad I found your site, I really found you
    by accident, while I was researching on Aol for something else, Regardless
    I am here now and would just like to say many thanks for a
    marvelous post and a all round exciting blog (I also love the
    theme/design), I don’t have time to read it all at the moment but I have bookmarked it and
    also added your RSS feeds, so when I have time I
    will be back to read a lot more, Please do keep up the awesome work.

  5. ligeixiao
    ligeixiao August 6, 2014

    赞!!!浏览过很多页面,终敌不过鸟哥一篇!

  6. aosie
    aosie March 30, 2014

    ob_end_clean();
    function handlerString($string)
    {
    return $string.’-‘.ord($string).’-‘.md5($string).’–;’;
    }
    ob_start(‘handlerString’);
    echo ‘xxxxxx’;
    ob_flush();
    flush();
    输出结果为:
    xxxxxx-120-dad3a37aa9d50688b5157698acfd7aee–;-0-d41d8cd98f00b204e9800998ecf8427e–;
    为什么多了一个0(ascii),求解释

  7. […] 鸟哥在这里提到:php buffer ob_*系列函数控制的是PHP自身的缓存 数据到浏览器显示,一般会经过三种缓存: php oupput buffering->webServer buffering->browser buffering->display. […]

  8. zhkzyth
    zhkzyth December 15, 2011

    我觉得加上下面这句可能容易理解点,=)
    “ob_flush()和flush()的区别。前者是把数据从PHP的缓冲中释放出来,后者是把不在缓冲中的或者说是被释放出来的数据发送到浏览器。所以当缓冲存在的时候,我们必须ob_flush()和flush()同时使用。”
    ——摘自http://www.surfchen.org/archives/125

  9. Rocky
    Rocky July 22, 2011

    Hi laruence,
    请教一个问题:能利用ob_flush,flush或某些http header来让浏览器提前认为服务器响应结束吗?(服务器在后台继续)

  10. Sun
    Sun May 19, 2010

    谢谢

  11. Anonymous
    Anonymous April 16, 2010

    很好,尤其在comet等需要特别注意cache的场景,需要注意这些

Comments are closed.