Save Browser Output To A File With PHP Output Buffering Functions

The PHP output buffering functions provide a handy way of intercepting the contents of the buffer before it is sent to the browser. The output is whatever is sent to the browser whenever you print something off. PHP allows you to capture this output in a buffer before it is sent to the browser.

Output buffering is controlled by two mechanisms. The first is through the php.ini directive output_buffering, which is usually set to off. It can be turned on by setting this to either on, or the number of bytes that the buffer can take up. When this byte allocation is full the output is sent to the browser.

The second mechanism is through the use of the ob_start() function, which turns on output buffering for the script it is being run on. If output buffering has been set in the php.ini file then this isn't needed, but if it has been set to 'off' then you will get some errors if you try to do anything with the buffer. To start output buffering just call the ob_start() function.

ob_start();

Whatever you try to print off now will not be output to the browser until the end of the script. To explicitly push the output to the browser you can call the ob_flush() function.

echo 'test';
ob_flush();

You can turn off output buffering at any time by calling either ob_end_clean() or ob_end_flush(). ob_end_clean() will turn off the top most buffer (you can have more than one) and discard the contents. ob_end_flush() will output the contents of the top most buffer then turn it off. Here is an easy way to use ob_end_flush() to flush and turn off all available output buffers and output their contents.

while (@ob_end_flush());

You can get the contents of the output buffer at any time (as long as you haven't turned it off) by calling the ob_get_contents() function. This returns the current buffer contents. Here is an example of it in action.

<?php
ob_start();
echo 'test ';
?>
some more text
<?php
$out = ob_get_contents();
ob_end_flush();
// $out now contains 'test some more text'.
?>

The ob_flush() function will empty the current output buffer and send this to the browser. So it is important to call this function after you have got the contents of the buffer. If you call it before you try to get the buffer contents there will be nothing there.

Using the ob_get_contents() function is how you can output text to both a file and the browser. The following example will write some text to the browser and also store this text in a variable that is written to a file at the end of the script. The file is given the current time stamp as a name. Make sure you have sufficient rights to write into this directory using chmod.

$out = '';
ob_start();
echo 'test';
$out .= ob_get_contents();
ob_flush();
echo ' some more text to add to the buffer';
$out .= ob_get_contents();
ob_end_flush();
// check that something was actually written to the buffer
if (strlen($out) > 0) {
 $file = 'debug/' . time() . '.html';
 touch($file); 
 $fh = fopen($file, 'w');
 fwrite($fh, $out);
 fclose($fh);
}

The ob_start() function can be called without any parameters, but you can supply the name of a function that will be used to pass the contents of the buffer through before it is sent to the browser. Using this mechanism is slightly easier as it can be easily removed from any script. The call back function must have a single string parameter, which is the contents of the buffer, and must return a string, preferably the contents of the buffer.

function bufferCallBack($buffer)
{
// check that something was actually written to the buffer
 if (strlen($buffer) > 0) {
  $file = 'debug/' . time() . '.html';
  touch($file);
  $fh = fopen($file, 'w');
  fwrite($fh, $buffer);
  fclose($fh);
 }
 return $buffer;
}
 
ob_start('bufferCallBack');
echo 'test';
echo ' some more text to add to the buffer';
ob_end_flush();

Be warned that the use of output buffering can lead to the apparent slowdown of your website due to everything being generated server side before being sent to the client.

Update: Added some advice about having correct permissions and corrected a variable name in the second example. Thanks to William for his email on pointing this out :)

Comments

thanks ! this helped me index 80000 webpages that little bit easier, I was making them into XML for a sitemap format. regards, paul
Permalink
Thanks man. Easy stuff but hard to find all in the same place with good examples
Permalink
A very good explaination, I've set this up to have dynamic filenames based on a list of possible dynamically created pages, it works perfectly.
Permalink

Add new comment

The content of this field is kept private and will not be shown publicly.
CAPTCHA
5 + 3 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.