ob_clean

Erases the contents of the active output buffer while leaving the buffer open.

Signature
ob_clean(): bool
  • Added in PHP 4.2.0

Return value

boolReturns true on success or false on failure.

Errors

Fails and emits an E_NOTICE when there is no active output buffer, or when the active buffer was started without the PHP_OUTPUT_HANDLER_CLEANABLE flag.

ob_clean() throws away everything written into the current output buffer since it was opened, then keeps buffering. It calls the buffer's output handler with the PHP_OUTPUT_HANDLER_CLEAN flag and discards whatever the handler returns, so a handler that transforms output never gets the chance to emit the discarded text.

When to reach for it

Reach for it when a render is half finished and you want to start over inside the same buffer: a template hits an error partway through, a validation failure means the success page must be replaced with an error page, or a loop builds one candidate output per iteration and only some of them survive.

What trips people up

The three cleaning functions are easy to confuse:

FunctionErasesCloses the bufferReturns contents
ob_cleanyesnono
ob_end_cleanyesyesno
ob_get_cleanyesyesyes

The other surprise is scope. ob_clean() erases the body only. Headers you queued with header() live outside the buffer stack and survive untouched, so an error path that cleans the buffer still ships whatever status code and content type it already set.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Discard a half-rendered template when a fatal validation error is discovered midway and render an error page instead.
  • Build several candidate outputs in a loop, keeping only the one that passes a check.
  • Suppress a noisy third-party function's echoed debug text while continuing to buffer your own output.

Frequently asked questions

What is the difference between ob_clean and ob_end_clean?

ob_clean() erases the buffer but leaves it open and still capturing output; ob_end_clean() erases it and closes it, dropping the nesting level by one.

Does ob_clean remove headers I already sent?

No. header() and setcookie() write to a separate header queue that the output buffer never holds, so cleaning the buffer leaves the status code and headers in place.

Why does ob_clean return false and emit a notice?

Because there was no active output buffer, or the active buffer was started without the PHP_OUTPUT_HANDLER_CLEANABLE flag. Check ob_get_level() before calling it.

More examples

The buffer level does not change

Only the two lines written after ob_clean() are printed. The level after cleaning is one higher than the starting level, showing that the buffer is still open and still capturing output.

Example · php
<?php
$before = ob_get_level();
ob_start();
echo "draft text";
$ok = ob_clean();
$after = ob_get_level();
echo "ob_clean returned: ", var_export($ok, true), "\n";
echo "level went from $before to $after\n";
ob_end_flush();

Re-rendering inside a template helper

Prints '- Widget' then '- (unnamed item)'. The blank row is written first and then erased, so the fallback replaces it rather than appending after it.

Example · php
<?php
function renderRow(array $row): string {
    ob_start();
    echo "- {$row['name']}\n";
    if ($row['name'] === '') {
        ob_clean();               // scrap the empty row
        echo "- (unnamed item)\n";
    }
    return ob_get_clean();
}

echo renderRow(['name' => 'Widget']);
echo renderRow(['name' => '']);

Discussion

  • Be the first to comment on this lesson.