Page 1 of 1

Sending output in determined chunks

Posted: Tue Mar 02, 2010 2:40 am
by Raging Pineapples
Hi all,

I'm using PHP to perform a fairly big process, which takes a while. I'm concerned that it has the tendency to buzz away forever on the server side and then finally output everything all at once. I would prefer it to output the page in 'stages' so the user gets some feedback.

Is there any way to force a PHP script to send its output 'so far' and then send another lot later, and another lot later, without stopping and restarting the script?

Something reminiscent of:

Code: Select all

 
$line = "A small dog\n";
send_it( $line );
$line = "called Bernard\n";
send_it( $line );
$line = "gave Sally\n";
send_it( $line );
$line = "a nip!\n";
send_it( $line );
 
To the user this would appear to load in 4 'steps'.

Thoughts?

Re: Sending output in determined chunks

Posted: Tue Mar 02, 2010 6:32 am
by davex
Hi Yes/No/Maybe I'm afraid is the answer.

Exactly how/when data is sent to the client is dependent on your PHP configuration, the web server software and potentially any other in-the-middle things such as proxies or web accelerators.

I have seen this discussed before (link escapes me) and the best (i.e. least-bad) option was to use output buffering (http://www.php.net/manual/en/book.outcontrol.php).

To do this you would start output buffering, flush the buffer every time you wanted to send data (I think that also clears it but you may want to check that) and then ob_end_flush it as a last step.

Please note that you will probably want to flush plenty of data on each occasion (maybe lots of HTML comments or similar) to ensure that the browser will load the data as often as possible. This will still not work in all circumstances with data only being returned in entirety to the browser.

Example:

Code: Select all

<?php
$pad_length=128;
$pad_text="pad";
$padding="\n<!-- ";
for($i=0; $i<$pad_length; $i++)
 {
 $padding.=$pad_text;
 }
$padding.="-->\n";
 
// do all your header stuff then
ob_start();
 
// output something and then
echo $padding;
ob_flush();
 
// output something else and then
echo $padding;
ob_flush();
 
// and so on
?>
Not ideal at all but I think it should work. Maybe. Good luck!

Cheers,

Dave.