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也可以, 只不过为了保证你代码的可移植性, 建议配套使用.

18 Comments

  1. Hotmail Login
    Hotmail Login 2018-03-20

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

  2. Zithromax
    Zithromax 2016-10-26

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

  3. Gordon
    Gordon 2016-04-21

    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 2015-06-04

    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 2014-08-06

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

  6. aosie
    aosie 2014-03-30

    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. zhkzyth
    zhkzyth 2011-12-15

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

  8. Rocky
    Rocky 2011-07-22

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

  9. Sun
    Sun 2010-05-19

    谢谢

  10. Anonymous
    Anonymous 2010-04-16

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

Leave a Reply

Your email address will not be published. Required fields are marked *