Nyxynyxx
Nyxynyxx

Reputation: 1183

Echo 'string' while every long loop iteration (flush() not working)

I have a loop that takes very long to execute, and I want the script to display something whenever the loop iteration is done.

echo "Hello!";

flush();

for($i = 0; $i < 10; $i ++) {
    echo $i;
    //5-10 sec execution time
    flush();
}

This does not display the echos until the entire script is completed. What went wrong?

Upvotes: 23

Views: 31853

Answers (7)

Amir Forsati
Amir Forsati

Reputation: 5968

Add this on the header of the script:

ob_start();
ob_implicit_flush();

Implicit flushing will result in a flush operation after every output call so that explicit calls to flush() will no longer be needed. Please note that adding implicit flushing in the script execution affects on performance. You can add a debugging mode for your script like:

ob_start();
define(DEBUG, 1);

if(DEBUG){
    ob_implicit_flush();
}

Upvotes: 0

krom
krom

Reputation: 153

Also make sure to output a Content-type header first. Flushing doesn't work for me without:

header( 'Content-type: text/html; charset=utf-8' );
for($i=0; $i<10; ++$i)  {
    echo "Loop<br />\n";
    ob_flush();
    flush();
    sleep(1);
}

Upvotes: 0

radoo
radoo

Reputation: 168

Make sure you first do:

@ini_set('zlib.output_compression', 0); @ini_set('implicit_flush', 1); @ob_end_clean();

and then just flush(); every time you need to output your echo'es to the browser.

Upvotes: 5

Grigoreas P.
Grigoreas P.

Reputation: 2472

try this

while (@ob_end_flush());      
ob_implicit_flush(true);

echo "first line visible to the browser";
echo str_pad("",1024," ");
echo "<br />";

sleep(5);

echo "second line visible to the browser after 5 secs";

Just notice that this way you're actually disabling the output buffer for your current script. So if you're trying to 'ob_end_flush()' after that you'll get a warning that there is no buffer to close.

Upvotes: 4

SteAp
SteAp

Reputation: 11999

In general, the desired behavior isn't possible is a deterministic/stable way using pure PHP and HTML.

If and how a browser renders a partial page depends on the browser, proxies and caches. Thus, even if the stuff works on your test machine, it's likely, that it does not on your production system.

The library xAjax provides a well-integrated solution to manage AJAX style updates with PHP. While xAjax might be dead as a project (at least right now), it still works fine.

Upvotes: 1

Gregory Burns
Gregory Burns

Reputation: 840

From PHP Manual:

flush() may not be able to override the buffering scheme of your web server and it has no effect on any client-side buffering in the browser. It also doesn't affect PHP's userspace output buffering mechanism. This means you will have to call both ob_flush() and flush() to flush the ob output buffers if you are using those.

echo "Hello!";
flush();
ob_flush();

for($i = 0; $i < 10; $i ++) {
    echo $i;
    //5-10 sec execution time
    flush();
    ob_flush();
}

-or- you can flush and turn off Buffering

<?php
//Flush (send) the output buffer and turn off output buffering
while (ob_get_level() > 0)
    ob_end_flush();

echo "Hello!";

for($i = 0; $i < 10; $i ++) {
    echo $i . "\r\n";
}

?>

Upvotes: 31

Julien Ducro
Julien Ducro

Reputation: 854

You could try to also use ob_flush() sometimes both are needed to work.

Upvotes: 0

Related Questions