DEV Community

Yahaya Oyinkansola
Yahaya Oyinkansola

Posted on

Output Buffering in PHP

Output buffering is a concept some developers find hard to understand. In this article, I would explain what it is so you can use it with better understanding in your PHP applications.

What is a buffer?

A buffer is a location in the memory (i.e RAM) of a computer that temporarily stores data for a period of time. An input device sends data to the computer, the data is processed and the output generated is stored in a buffer. Take for example a microphone and speaker, when someone speaks through the microphone, the sound is sent to a buffer before it is sent to the speaker, or else what the person says would not be heard well.

In the case of the web, a buffer is a location in memory or cache that stores the output to be sent to the browser.

What is output buffering?

Output buffering is a technique that allows you control when output is sent from your script to the browser. This is important to understand because without output buffering, the browser would be receiving the output in pieces. One thing that makes output buffering very useful is the control it gives you to determine how your output should be sent to the browser. Here is an example of how output is sent with and without output buffering.

Output without buffering

Output with buffering

Diagram created by Julian from Stackoverflow

With this terms covered, let's see how to implement output buffering in PHP.

1. ob_start()

In other to do output buffering in PHP, you need to turn it on. When output buffering is on, no output is sent from your script, rather it is stored in an output buffer. Once the script finishes executing, PHP would send the contents stored in the output buffer to the browser. The only output you can send when output buffering is on are headers.

  <?php
     ob_start();

     echo "Hello world";

     setcookie("website", "hashnode.com");
Enter fullscreen mode Exit fullscreen mode

In this example, "Hello world" is not immediately sent to the browser but setcookie() runs immediately. When the script finishes executing, "Hello world" is sent from the output buffer to the browser.

THERE ARE 2 POINTS I WANT TO NOTE

  1. Output buffering is enabled by default most times in PHP. You can check by

    • Going to your php.ini config file and looking for the output buffering configuration setting. If it has a value of 4096, then output buffering is on
    • Using the browser. If you use XAMPP for instance, you can go to this link and check if output buffering is on or off.
  2. You can call ob_start() more than once in your script. When you call ob_start(), you are turning on output buffering at a SPECIFIC LEVEL.
    What does this mean?, since output buffering is on by default, the first level of the output buffer is at 0, when you call ob_start() in your script, the level changes to 1, if you call it again, it changes to 2, if you call it again, it changes to 3, I think you get the pattern now. This is important to understand because the level where output buffering is turned on determines where it would work.

  <?php
       // Where this comment line is, output buffering is currently at level 0
       ob_start(); // The level changes to 1
       ob_start(); // The level changes to 2
Enter fullscreen mode Exit fullscreen mode

2. ob_get_contents()

This function retrieves the content stored in the output buffer. With the help of this function, you can manipulate the output before sending it to the browser.

<?php
  ob_start();

  echo "hello world";
  $content = strtoupper(ob_get_contents());
  ob_end_clean();

  echo $content; // displays HELLO WORLD in the browser
Enter fullscreen mode Exit fullscreen mode

3. ob_get_status()

This function returns information about the current output buffer, depending on the level where output buffering started.

<?php
  ob_start();

  var_dump(ob_get_status());

/*
    ["name"] => string(22) "default output handler"
    ["type"] => int(0)
    ["flags"] => int(112)
    ["level"] => int(1)
    ["chunk_size"] => int(0)
    ["buffer_size"] => int(16384)
    ["buffer_used"] => int(5)
 */
Enter fullscreen mode Exit fullscreen mode

4. ob_get_level()

This function returns a count of all the output buffers that are running, including the default one.

<?php
  ob_start();
  echo ob_get_level(); // returns 2
Enter fullscreen mode Exit fullscreen mode

5. ob_flush()

This function flushes (i.e sends) the content stored in the output buffer to the browser. After the output is sent, the output buffer is emptied.

<?php
  ob_start();
  echo "hello world";
  ob_flush();
  var_dump(ob_get_contents()); // At this point, there is no content in the output buffer
Enter fullscreen mode Exit fullscreen mode

6. ob_end_flush()

This function does the same thing with ob_flush(), the only difference is immediately ob_end_flush() sends the output, it turns off output buffering.

<?php
  ob_start();
  echo "hello world";
  ob_end_flush();

  var_dump(ob_get_contents()); // returns false
Enter fullscreen mode Exit fullscreen mode

** N/B :- If you don't get false, it is because when output buffering is turned off, buffering would go back to the previous level, which in this case would be 0. So you would need to call ob_end_flush() again to turn it off at that level.**

7. ob_clean()

This function removes what is stored in the output buffer. You would call this function last in the output buffering process because if you need to get or send the content stored in the output buffer, calling ob_clean() would clean the contents of the output buffer and there won't be any content to receive or send.

<?php
  ob_start();
  echo "hello world";
  ob_clean();

  var_dump(ob_get_contents()); // returns an empty string
Enter fullscreen mode Exit fullscreen mode

8. ob_end_clean()

This function removes the contents stored in the topmost output buffer and turns off output buffering at that level. The topmost output buffer is the output buffering process you started last in your script.

<?php
  ob_start(); // 1
  echo "hello world";
  ob_start(); // 2 - This is the topmost output buffer
  echo "welcome to hashnode";
  ob_end_clean(); // This will clean the output buffer and turn off output buffering at level 2
Enter fullscreen mode Exit fullscreen mode

9. ob_get_clean()

This function is really cool because you can get the content stored in the output buffer and turn off output buffering at the same time. It's like using ob_get_contents() and ob_end_clean() together.

<?php
  ob_start(); // 1
  echo "hello world";
  $content = ob_get_clean();

  echo $content; // shows hello world in the browser
  var_dump(ob_get_status()); // returns information about the output buffer at level 0
Enter fullscreen mode Exit fullscreen mode

This is the basics of getting started with output buffering, you can read more about it from PHP's documentation website and implement it in your web applications. What still confuses you about output buffering?, I would love to know and help you out.

Connect with me on Twitter and Linkedin and let's share beautiful ideas and knowledge

Top comments (5)

Collapse
 
studiowizjo profile image
studiowizjo

It is especially usefull when dealing with expensive tasks which takes time (eg. sending bunch of e-mails, importing data, generating reports and so on). Using this approach you can track progress of execution instead of waiting till scripts will end.

Collapse
 
kansoldev profile image
Yahaya Oyinkansola

Very true, output buffering helps in this area too

Collapse
 
gpatsoulis profile image
gpatsoulis

Why use output buffering instead of a variable, (a variable is a named memory location which temporarily stores data, much like a buffer)

$output = '';
$output .= 'Hello';
$output .= ' world';

echo $output;

What are the benefits of using output buffering vs a variable ?

Collapse
 
kansoldev profile image
Yahaya Oyinkansola

Using output buffering over a variable is more convenient when you want to send header information to the browser and output has already been sent from the PHP script. You might have come across "Headers already sent" error before, with output buffering, you can solve this issue because the output would be buffered so it gives space for the header information to be sent to the browser just before the output gets sent.

Collapse
 
lunadxp profile image
coronelius

I feel like things like this are not recommended in general as it's hard to debug and understand what's going on when codebase grows.
But certainly would have usage in certain circumstances.