So, I'm looking for something more efficient than this:
<?php
ob_start();
include 'test.php';
$content = ob_get_contents();
file_put_contents('test.html', $content);
echo $content;
?>
The problems with the above:
- Client doesn't receive anything until the entire page is rendered
- File might be enormous, so I'd rather not have the whole thing in memory
Any suggestions?
Interesting problem; don't think I've tried to solve this before.
I'm thinking you'll need to have a second request going from your front-facing PHP script to your server. This could be a simple call to http://localhost/test.php. If you use fopen-wrappers, you could use fread() to pull the output of test.php as it is rendered, and after each chunk is received, output it to the screen and append it to your test.html file.
Here's how that might look (untested!):
Here you go x-send-file, use mod_xsendfile to send file efficiently, really easy.
A better way to do this is to use the first two parameters accepted by
ob_start
:output_callback
andchunk_size
. The former specifies a callback to handle output as it's buffered, and the latter specifies the size of the chunks of output to handle.Here's an example:
In this example, the output buffer will be flushed (sent) for every 4096 bytes of output (and once more at the end by the
ob_end_flush
call). Each time the buffer is flushed, the callback$write_ob_to_file
will be called and passed the latest chunk. This gets written to test.html. The callback then returnsfalse
, meaning "output this chunk as is". If you wanted to only write the output to file and not to PHP's output stream, you could return an empty string instead.Pix0r's answer is what you want unless you actually need it "included" rather than just executed. For example, if you have login information before the test.php, it will not get passed into the file if you call it with fopen.
If you need it genuinely included, then what you have is the simplest method, but if you want constant output, you'll need to actually write test.php in a manner that outputs as well as stores the information as it goes. As far as I know there's no way to both collect buffer and output it as you go.