ob_clean
Erases the contents of the active output buffer while leaving the buffer open.
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:
| Function | Erases | Closes the buffer | Returns contents |
|---|---|---|---|
ob_clean | yes | no | no |
ob_end_clean | yes | yes | no |
ob_get_clean | yes | yes | yes |
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
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.
<?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.
<?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