Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you run a long PHP script and keep sending updates to the browser via HTTP?

How do you run a long PHP script and keep sending updates to the browser via HTTP?

Something to do with output buffering but I don't know exactly how.

like image 864
Robin Rodricks Avatar asked Jun 08 '10 09:06

Robin Rodricks


3 Answers

Output Buffering is thinking in the right direction, you start output buffering with ob_start() just like you would with sessions (session_start) somewhere in the top of your script, before any output is sent.

Then, you can use ob_flush and flush to keep flushing the output. For example, if you are in a foreach loop and at the end of each loop you want to output the new row and wait 1 second you would can do that.

But also look at set_time_limit, because otherwise people might experience a timeout after 30 seconds or so.

Another quick note, some browsers require a minimum number of bytes of output before they actually start showing it. I'm not sure what amound of bytes it was, I think it was around the 4000. Also, some browsers won't render certain elements (like tables) until they are closed. So flushing won't work there either.

like image 174
CharlesLeaf Avatar answered Sep 22 '22 09:09

CharlesLeaf


This looks like what you are after:

output buffering, PHP sends the output of your scripts to your web server as soon as it's ready - this might be line by line or code block by code block.

Output Buffering

The ob_start() function is used to create a new output buffer, and you can immediately start writing to it by printing out content as normal. Once you have a buffer open, there are two ways to close it: ob_end_flush() and ob_end_clean(), both of which end the buffer, but do so in slightly different ways. The former ends the buffer and sends all data to output, and the latter ends the buffer without sending it to output, effectively wiping out any information you saved in there. Every piece of text outputted while an output buffer is open is placed into that buffer as opposed to being sent to output. Consider the following script:

<?php
  ob_start();
  print "In first buffer!\n";
  ob_end_flush();
  ob_start();
  print "In second buffer!\n";
  ob_end_clean();
  ob_start();
  print "In third buffer!\n";
?>

That script will output "In first buffer" because the first text is placed into a buffer then flushed with ob_end_flush(). The "In second buffer" won't be printed out, though, because it's placed into a buffer which is cleaned using ob_end_clean() and not sent to output. Finally, the script will print out "In third buffer" because PHP automatically flushes open output buffers when it reaches the end of a script.

like image 33
Kieran Andrews Avatar answered Sep 20 '22 09:09

Kieran Andrews


You can also have a kind of background task, and an interface giving you the progress rate.

for instance, a page called job.php

<?php
    for ($i=0; $i<100; ++$i)
    {
       store($i);
       // long stuff
       sleep(42);
    }
?>

and progress.php

<?php
      return get($i);
?>

Then some ajax calls to progress.php?task=mytaskid and update the GUI. I have seen such method for a "big" file upload and found it great.

Edit: sorry, this doesn't exactly respond the initial question.

like image 43
Aif Avatar answered Sep 19 '22 09:09

Aif