locked
PHP Output Buffer Flushing RRS feed

  • Question

  • User-381469998 posted

    Hello Guys,

    Got an issue with the PHP output buffers when using FastCGI (on IE6 with PHP 5.2.1); the following code works fine with php-cgi.exe directly (output_buffering and implicit_flush set to 0 in php.ini).

    Code:

    <?php
    for($i=0; $i < 10; $i++){
        echo $i . '<br />';
        flush();
        sleep(1);
    }
    ?>

    Expected Result:

    Each incrementing digit is written by the browser, every one second, whilst the request/response is still active.

    Actual Result with FastCGI:

    All the digits are written by the browser and the end of the request/response; output is always buffered.

    Thursday, February 22, 2007 8:08 AM

All replies

  • User-381469998 posted

    Also, if using output_buffering in php.ini; the following code should flush correctly but again doesn't with FastCGI.

    Code:

    <?php
    for($i=0; $i < 10; $i++){
        echo $i . '<br />';
        ob_flush();
        flush();
        sleep(1);
    }
    ?>

    Thursday, February 22, 2007 8:14 AM
  • User-679828332 posted

    Hi Red Fox UK,

    Great bug description! :-) For performance reasons and interoperability with some ASP.NET features, the current design works like this: We entirely buffer responses < 1mb and then send them at once.

    On IIS 7, an idea is to have the module honour the system.webServer/handlers/add@responseBufferLimit setting. We could also expose this as a setting on IIS 6.

    The FastCGI protocol does not support the concept of flushing. But by setting the module/isapi bufferLimit to size 0 it would result in us sending whenever PHP gave it data.

    Out of curiousity: Where is flushing used/useful?

    Thanks,

    Rick.

    Thursday, February 22, 2007 12:49 PM
  • User-381469998 posted

    Hello Rick,

    Exposing the setting would be usefull for IIS6 - but I dont understand what it does exactly, especially since PHP CGI on IIS6 and buffer flushing works fine; and even works when used in ASP.

    Buffer flushing has all sorts of uses: progress reports, helping pages that have long load times, etc...

    A good example is the DNS Report service at http://www.checkdns.net/quickcheck.aspx?domain=microsoft.com&detailed=1 - if their "results" page didnt show you the result of each DNS test as it progressed (flushed) you could be waiting several minutes staring at a blank screen until ALL DNS tests had been completed.

    Thursday, February 22, 2007 12:59 PM
  • User-381469998 posted

    Another problem related to output buffer flushing... The following code DOES flush correctly (but it needs an inital amount of data to do so for some reason), BUT a major problem - the HTTP connection never ends and therefore the browser is still "loading" even after the PHP script should have ended!

    <?php
    ob_implicit_flush();
    for($i=0; $i < 1030; $i++){
        echo ' ';
    }
    for($i=0; $i < 10; $i++){
        echo $i . '<br />';
        sleep(1);
    }
    ?>

    Friday, February 23, 2007 8:19 AM
  • User239750981 posted

    I am using plain CGI exe's in IIS 7 and I am finding the same caching/buffering problem, where it only sends everything all at once after the CGI exits.

    Using the information about responseBufferLimit, I tried adding an attribute to the CGI-exe settings in the applicationHost.control file, but it didn't help:

     ...
                <add name="CGI-exe" path="*.exe" verb="*" modules="CgiModule" resourceType="File" requireAccess="Execute" allowPathInfo="true" responseBufferLimit="1024" />

    ...

    If anyone knows how to work around this in IIS7, please let me know!  It is critical for our web application to be able to send browser updates during processing.

    Wednesday, August 13, 2008 6:27 PM
  • User511787461 posted

    Can you start a new thread under one of the IIS7 forums - possibly this.  This will probably require collecting failed request tracing to see what is going on.

    Monday, August 18, 2008 11:04 AM
  • User239750981 posted

    I spoke with Microsoft this week and found out the scoop:

    The @responseBufferLimit attribute that I added in my post above is the correct way to control buffering.  It initially did not work for me because the website had a locally scoped element <add name="CGI-exe" .../>.  Once I added the @responseBufferLimit attribute to that entry, everything worked !!

    Also, note that responseBufferLimit="0" will turn buffering completely off, which is the same behavior as IIS 6.

    Monday, August 18, 2008 12:32 PM
  • User-2140010589 posted

    Does anyone know the effect of setting responseBufferLimit="0" is on the performance improvements created by the buffer itself? Primarily that the IIS FastCGI implementation is very php process efficient because it buffers respones and is able to reuse a php process once the page is complete, but not sent to the client yet. Will it remove this efficiency also?

    -Stephen

    Monday, August 18, 2008 11:11 PM