Search code examples
phpapacheoutput-buffering

Output buffering, hierarchical?


Output buffering in PHP is fun. It simplifies many things. I use ob_start() at the top of the script and ob_get_clean() (or any other function) at the bottom.

Between those two calls is it possible to call those functions again, without interfering the parent calls.

Is this type of code valid ? (it works fine, but...) Is this a good habit ?

<?php

ob_start(); //NOTICE !!!

echo '<p>echos of the top of the script</p>';
echo GetSomeOtherData(true);
echo '<p>echos after GetSomeOtherData()</p>';

$data = ob_get_clean(); //NOTICE !!!
echo $data;

//just a function to return something, with the help of output buffering
function GetSomeOtherData($toReturn)
{

    ob_start();     //NOTICE !!!
    echo '<p>This has been rendered inside a function</p>';
    $function_data = ob_get_clean();    //NOTICE !!!

    if($toReturn===true)
    {
        return $function_data;
    }
    else
    {
        //may be an error | return something else
        return '<p>An Error</p>';
    }
}
?>

Solution

  • From the ob_start() manual:

    Output buffers are stackable, that is, you may call ob_start() while another ob_start() is active. Just make sure that you call ob_end_flush() the appropriate number of times. If multiple output callback functions are active, output is being filtered sequentially through each of them in nesting order.

    So it is perfectly valid to assume that an ob_end/get will end/return the matching ob_start e.g.:

    ob_start();
      echo "<div class=outer>";
      ob_start();
        echo "<div class=inner></div>";
      $inner = ob_get_clean(); // <div class=inner></div>
      echo "</div>";
    $outer = ob_get_clean();     // <div class=outer></div>