dbazile
dbazile

Reputation: 115

Looping on Output Buffers

I am seeing some behavior from ob_start() and ob_end_*() that seems very counterintuitive.

In the spirit of neatness, my algorithm is:

  1. Open buffer
  2. Do some things
  3. Save the buffer to a string
  4. Close the buffer

I'm getting the following notices at runtime for each loop case beyond the first case.

Notice: ob_end_clean(): failed to delete buffer. No buffer to delete in C:...\testing\TestOBError.php on line 21

Notice: ob_end_clean(): failed to delete buffer. No buffer to delete in C:...\testing\TestOBError.php on line 21

Notice: ob_end_clean(): failed to delete buffer. No buffer to delete in C:...\testing\TestOBError.php on line 21

Current story payload: `one'.

Current story payload: `two'.

Current story payload: `three'.

Current story payload: `four'.

Example code (TestOBError.php):

<?php
class Story {
    public $payload;
    public function __construct($payload) {
        $this->payload = $payload;
    }
}

$stories = array();
$stories[] = new Story('one');
$stories[] = new Story('two');
$stories[] = new Story('three');
$stories[] = new Story('four');

$foo = "";

foreach ($stories as $story) {
    ob_start();
    require 'TestOBError_Foo.php';
    $foo .= ob_get_clean();
    ob_end_clean();
}

print $foo;

?>

Contents of TestOBError_Foo.php:

<p>Current story payload: `<?php print $story->payload; ?>'.</p>

Am I just misusing the output buffer? Can anyone tell me the "right way" to do this?

I am running PHP version 5.4.7.

Upvotes: 3

Views: 2223

Answers (2)

Reza Mamun
Reza Mamun

Reputation: 6189

Very simple in a loop and working as expected :)

foreach($Records as $pp=>$Record){
    ob_start();
    include(STYLESHEETPATH.'/inc/set-record-vars.php');
    include(STYLESHEETPATH.'/inc/make-html-row.php'); //Here direct HTML output;
    $jsItems[] = array(
        'id' => $proxyId,
        'row' => ob_get_contents()
    );
    ob_end_clean();
}

Upvotes: 0

John Kugelman
John Kugelman

Reputation: 362087

You don't need to call both ob_get_clean() and ob_end_clean(). Either do this:

$foo .= ob_get_clean();

Or do this:

$foo .= ob_get_contents();
ob_end_clean();

From the PHP manual:

string ob_get_clean ( void )

Gets the current buffer contents and delete current output buffer.

ob_get_clean() essentially executes both ob_get_contents() and ob_end_clean().

Upvotes: 3

Related Questions