How to Flush Output After Each 'Echo' Call

How to flush output after each `echo` call?

Edit:

I was reading the comments on the manual page and came across a bug that states that ob_implicit_flush does not work and the following is a workaround for it:

ob_end_flush();

# CODE THAT NEEDS IMMEDIATE FLUSHING

ob_start();

If this does not work then what may even be happening is that the client does not receive the packet from the server until the server has built up enough characters to send what it considers a packet worth sending.


Old Answer:

You could use ob_implicit_flush which will tell output buffering to turn off buffering for a while:

ob_implicit_flush(true);

# CODE THAT NEEDS IMMEDIATE FLUSHING

ob_implicit_flush(false);

PHP flushing output as soon as you call echo

The script works fine from CLI, displaying "Fun", waiting 5 secs before displaying "<br>Mo".

For a browser the results might be a bit different because:

  1. The browser wont start rendering right away. Getting 3 bytes of data for HTML document isn't enough to do anything, so it'll most likely wait for a few more.
  2. Implicit IO buffering on the lib level will most likely be active until a newline is received.

To work around 1) use text/plain content type for your test; 2) needs newlines, so do an echo "Fun\n"; and echo "<br>Mo\n"; Of course you wont be using text/plain for real HTML data.

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

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";
}

?>

How to flush data to browser but continue executing

ob_flush writes the buffer. In other words, ob_flush tells PHP to give Apache (or nginx/lighttpd/whatever) the output and then for PHP to forget about it. Once Apache has the output, it does whatever it wants with it. (In other words, after ob_flush it's out of your control whether or not it gets immediately written to the browser).

So, short answer: There's no guaranteed way to do that.

Just a guess, you're likely looking for AJAX. Whenever people are trying to manipulate when page content loads as you're doing, AJAX is almost always the correct path.

If you want to continue a task in the background, you can use ignore_user_abort, as detailed here, however, that is often not the optimal approach. You essentially lose control over that thread, and in my opinion, a web server thread is not where heavy processing belongs.

I would try to extract it out of the web facing stuff. This could mean a cron entry or just spawning a background process from inside of PHP (a process that though started from inside of script execution will not die with the script, and the script will not wait for it to finish before dying).

If you do go that route, it will mean that you can even make some kind of status system if necessary. Then you could monitor the execution and give the user periodic updates on the progress. (Technically you could make a status system with a ignore_user_abort-ed script too, but it doesn't seem as clean to me.)

how to make echo print out right away in PHP?

If output buffering is on, then flushing it is the only way to output anything to the browser. If you want to output right away then turn of output buffering. If that is not in your control you can just call ob_end_flush() at the srart of your script which will turn the output buffering off. There is no way however to let some messages pass, and some not (without writing custom echo/print functions)

calling ob_end_flush() will flush and turn off the top most output buffer. To make sure all output buffers are turned off and flushes you can easily do this:

while (@ob_end_flush());

How do echo out progress on MAMP using flush()

Output buffering is a mechanism for controlling how much output data
(excluding headers and cookies) PHP should keep internally before
pushing that data to the client. If your application's output exceeds
this setting, PHP will send that data in chunks of roughly the size
you specify. Turning on this setting and managing its maximum buffer
size can yield some interesting side-effects depending on your
application and web server. You may be able to send headers and
cookies after you've already sent output through print or echo. You
also may see performance benefits if your server is emitting less
packets due to buffered output versus PHP streaming the output as it
gets it. On production servers, 4096 bytes is a good setting for
performance reasons.

Note: Output buffering can also be controlled via Output Buffering Control
functions.

php.ini Possible Values:

On = Enabled and buffer is unlimited. (Use with caution) 
Off = Disabled
Integer = Enables the buffer and sets its maximum size in bytes.
eg: output_buffering = Off

Note: This directive is hardcoded to Off for the CLI SAPI

http://php.net/output-buffering

A Working example if output_buffering is set to 4096

<?php
ob_start();
// Output string to overflow browser php.ini output_buffering setting.
echo str_repeat(PHP_EOL, 4097);

for ($i=0; $i<5; $i++) {
echo PHP_EOL.$i;
ob_flush();
flush();
sleep(1);
}
ob_end_flush();
?>

PHP Flush All Levels of Output Buffering

You don't need ob_flush() and ob_end_flush(). Your while loop is sufficient.

You should also look at: http://us.php.net/manual/en/function.ob-implicit-flush.php

Your need for flush() after ob_end_flush() depends on how you set this function.



Related Topics



Leave a reply



Submit