PHP Output Buffering – A Beginner’s Guide

INTRODUCTION
BUFFER MAGIC

Welcome to a beginner’s tutorial on PHP output buffering. You have probably seen this output buffering thing everywhere on the Internet, maybe even used it yourself. But just what is output buffering, and what does it do!? Why is it so important, and what kind of sorcery does it do? That is what we will go through in this guide – To help you better understand output buffering. Read on to find out!

ⓘ I have included a zip file with all the example code at the start of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.

 

 

 

PREAMBLE
SOURCE CODE DOWNLOAD

First, here is the download link to the example source code as promised.

 

SOURCE CODE DOWNLOAD

Click here to download the source code, I have released it under the MIT license, so feel free to build on top of it or use it in your own project.

 

QUICK NOTES

If you spot a bug, please feel free to comment below. I try to answer questions too, but it is one person versus the entire world… If you need answers urgently, please check out my list of websites to get help with programming.

 

SECTION A
WHAT IS OUTPUT BUFFERING?

Before we go into the tiny details of (almost) every output buffering function, let us start by answering the very basic question – What on Earth is output buffering? What does it do? What is it for?

 

THE HELLO WORLD OF OUTPUT BUFFERING

So, you think that you have graduated from “hello world”, and know the basics of PHP well enough? Or do you? Let us revisit the very simple script again:

1a-hello.php
<?php
echo "hello";
echo " world";
// Output will be "hello world"

Ha. Child’s play, a piece of cake. The output is as expected, but let us now add output buffering to the equation.

1b-hello.php
<?php
ob_start();
echo "hello";
echo " world";
// Output will be "hello world"

What!? Isn’t this exactly the same as without output buffering? What is happening here and is this some kind of a joke? Is output buffering broken, or are the developer so bored that they have to create a troll function? Keep calm, and here is what happened.

  • By default, PHP works without any sort of buffering; PHP is an impulsive fella who will send stuff to the output stream immediately.
  • Without buffering, echo "hello" and echo " world" will get sent to the output stream instantly as they are being called. I.E. There are 2 different outputs in this case.
  • But by enabling buffering, it is like telling PHP  – Stop it right there, you hasty bugger. Hold your horses on the output until I tell you to release it.
  • So once we start the buffering, both echo "hello" and echo " world" will get collected into a buffer instead of directly into the output stream.
  • Only at the end of the script will the buffer be released into the output stream. I.E. There is only one collective output in this case.

 

BUFFERING VS NONE

Maybe an illustration will explain things better.

PHP Output Buffering – How it works

 

WHAT IS IT GOOD FOR?

The uses of output buffering may not be very obvious at first, but without buffering, all the dynamic HTML and CSS that you generate with PHP will be sent out in bits-and-pieces.

  • Turning on output buffering will decrease the amount of time it takes to download and render the HTML. Simply because it is no longer being sent in pieces, but as “one big chunk”.
  • The even better part is when you save the buffer as a “completely rendered” HTML file. This will save your server resources from needlessly crunching the same pieces of data over-and-over again.
  • You can also employ the same “save the buffer to a file” tactic on generated documents – PDF files, spreadsheets, and more.
  • It is also kind of helpful when you deal with a function that echoes out values, that you rather store it somewhere else as a variable.

 

 

THE DISADVANTAGES

Yes, output buffering is not the perfect solution for everything.

  • The output will only be released when everything is done – This may not be good for massive data crunching scripts, where you force the user to stare at an empty screen for a long time.
  • Putting massive amounts of data into the cache also means consuming a lot of system memory.
  • Output buffering does not really sense for real-time systems… You just want to output stuff quickly and instantly.

 

SECTION B
OUTPUT BUFFERING BASICS

Now that you have a good idea of what output buffering is and what it does, let us now dive into some of the basics and some examples.

 

1) OB_START

As with the “hello world” example above, calling ob_start() will start the output buffering. All output after calling this function will be stored into an “invisible holding cell” buffer.

1b-hello.php
<?php
ob_start();
echo "hello"; // Buffer now holds "hello"
echo " world"; // Buffer now holds "hello world"
// Output will be "hello world"

 

2) OB_CLEAN

ob_clean() will clean out everything in the output buffer, but take note that it will not output anything.

2-clean.php
<?php
ob_start();
echo "hello"; // Buffer now holds "hello"
echo " world"; // Buffer now holds "hello world"
ob_clean(); // Buffer is now cleaned out
// No output - Buffer is empty

 

3) OB_FLUSH

ob_flush() will output the current buffer, then it will clean out everything inside it.

3-flush.php
<?php
ob_start();
echo "hello"; // Buffer now holds "hello"
echo " world"; // Buffer now holds "hello world"
ob_flush(); // Output "hello world", buffer now empty

echo "foo"; // Buffer now holds "foo"
echo " bar"; // Buffer now holds "foo bar"
// Buffer will automatically output "foo bar"

 

4) OB_END_CLEAN

ob_end_clean() will clear all the contents inside the current buffer, then stop the buffering.

4-end-clean.php
<?php
ob_start();
echo "hello"; // Buffer now holds "hello"
echo " world"; // Buffer now holds "hello world"
ob_end_clean(); // Clear buffer and stop
 
echo "foo"; // Immediately output "foo"
echo " bar"; // Immediately output " bar"

 

 

5) OB_END_FLUSH

ob_end_flush() will output all the contents inside the current buffer, then stop the buffering.

5-end-flush.php
<?php
ob_start();
echo "hello"; // Buffer now holds "hello"
echo " world"; // Buffer now holds "hello world"
ob_end_flush(); // Output "hello world", buffering stops
 
echo "foo"; // Immediately output "foo"
echo " bar"; // Immediately output " bar"

 

6) OB_GET_CONTENTS

ob_get_contents() will return all the data inside the buffer.

6-get-contents.php
<?php
ob_start();
echo "hello"; // Buffer now holds "hello"
echo " world"; // Buffer now holds "hello world"
$buff = ob_get_contents(); // $buff is now "hello world"
ob_end_clean(); // Stop buffering, clean it out

$buff .= " foo bar!"; // $buff now holds "hello world foo bar!"
echo $buff;

 

7) OB_GET_CLEAN

ob_get_clean() will return all the data inside the buffer, then clean it out.

7-get-clean.php
<?php
ob_start();
echo "hello"; // Buffer now holds "hello"
echo " world"; // Buffer now holds "hello world"
$buff = ob_get_clean(); // $buff is now "hello world", buffer is now empty

$buff .= " foo bar!"; // $buff now holds "hello world foo bar!"
echo $buff;

 

8) OB_GET_FLUSH

ob_get_flush() will return all the data inside the buffer, output it, then clean it out.

8-get-flush.php
<?php
ob_start();
echo "hello"; // Buffer now holds "hello"
echo " world"; // Buffer now holds "hello world"
$buff = ob_get_flush(); // $buff is now "hello world", output "hello world", empty buffer.

$buff .= " foo bar!"; // $buff now holds "hello world foo bar!"
echo $buff;

 

9) OB_GET_LENGTH

ob_get_length() will return the current size of the buffer, in bytes.

9-get-length.php
<?php
ob_start();
echo "hello"; // Buffer now holds "hello"
echo " world"; // Buffer now holds "hello world"
$bytes = "Buffer is now " . ob_get_length() . " bytes";
ob_end_clean();
echo $bytes;

 

 

SECTION C
ACTUALLY USEFUL EXAMPLE

With that, you should be thinking – What practical use does output buffering have? So here is one actually useful example, where we save a dynamically generated HTML file.

 

THE SCRIPT

eg-html-cache.php
<?php
// Serve cached file if it exists
$file = 'cache.html';
if (file_exists($file)) {
  require $file; 
}

// Else, generate the page
else {
  // Let's say that you extracted some data from the database
  $user = [
    "name" => "John Doe",
    "email" => "John@doe.com",
    "hobby" => "Football, Softball, Basketball, Racquetball, Baseball, Volleyball, Handball",
    "pets" => "Doge, Cate, Birb"
  ];

  // Buffer start
  ob_start();

  // Generate HTML ?>
  <!DOCTYPE html>
  <html>
    <head>
      <title>Cache Example</title>
    </head>
    <body>
      <table><?php
        foreach ($user as $k=>$v) {
          printf("<tr><td>%s</td><td>%s</td></tr>", $k, $v);
        }
      ?></table>
    </body>
  </html>
  <?php
  // Save the buffer to cache file
  $stream = fopen($file, 'w');
  fwrite($stream, ob_get_contents());
  fclose($stream);
}

 

THE EXPLANATION

This example should be pretty easy to understand – It puts a dynamically generated HTML page into the buffer, then saves it into an actual HTML file. The next time this page loads, it will grab that cached filed instead, and not redo all the dynamic generation again.

A pretty neat simple trick that will save you plenty of system resources. Combine this method with an HTML minifier, and this will give you quite a good speed boost as well.

 

 

EXTRA
SUMMARY

That’s all for the code, and here is a small summary that may be useful to you.

 

THE SUMMARY

Function Description
ob_start Start buffering.
ob_clean Clean out the buffer, no output.
ob_flush Output and clean out the buffer.
ob_end_clean Clean out the buffer, and stop buffering.
ob_end_flush Output the buffer, clean it, and stop.
ob_get_contents Returns the current buffer contents.
ob_get_clean Returns the current buffer contents, then clean it out.
ob_get_flush Returns the current buffer contents, output it immediately, then clean it out.
ob_get_length Get the size of the buffer, in bytes.

But of course, these are only a few of the common basics of output buffering. If you need more output buffering yoga – Please visit the official PHP function reference.

 

CLOSING
WHAT’S NEXT?

Thank you for reading, and we have come to the end of this guide. I hope that it has helped you to better understand, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!

Leave a Comment

Your email address will not be published. Required fields are marked *