PHP ob_clean() Function: Everything You Need to Know
As a PHP developer, you may need to clear the output buffer to start fresh. The ob_clean() function is a built-in function in PHP that allows you to clear the
The PHP ob_clean() function discards everything written to the current output buffer without turning buffering off. It's the function you reach for when your script has already produced some output, but you've decided that output is wrong (a leftover debug var_dump, a half-rendered template, an error message) and you want to throw it away and keep generating fresh content.
This page covers what ob_clean() does, its signature and return value, the gotchas that trip people up (especially the difference from ob_end_clean()), and practical patterns for using it.
What output buffering is
Normally PHP sends output to the client the moment you echo it. Output buffering changes that: after you call ob_start(), everything you print is captured into an in-memory buffer instead of being sent immediately. Nothing leaves PHP until you flush the buffer or the script ends.
That delay is what makes buffering useful — while output sits in the buffer you can still:
- send or modify HTTP headers (
header(),setcookie()) even after printing, - inspect, rewrite, or discard the captured output,
- compress the whole response before sending it.
ob_clean() is the "discard" operation in that list.
Syntax
ob_clean(): bool- Parameters: none.
- Return value:
trueon success,falseon failure. It fails (and emits a notice/warning) when there is no active output buffer to clean.
A basic example
<?php
ob_start(); // start buffering
echo "This text is buffered.\n";
ob_clean(); // throw the buffered text away
echo "Only this line is shown.\n";
ob_end_flush(); // send remaining buffer to outputOutput:
Only this line is shown.The first echo went into the buffer, ob_clean() emptied it, and only the second echo survived. Note that buffering is still on after ob_clean() — that's why the final ob_end_flush() is needed to actually emit the second line.
A real use case: discarding a broken render
ob_clean() shines when you generate output optimistically and then hit a condition that invalidates it:
<?php
function renderUser(?array $user): string
{
ob_start();
echo "<div class='card'>";
echo " <h2>" . ($user['name'] ?? '') . "</h2>";
if (empty($user)) {
ob_clean(); // scrap the half-built card
echo "<p>User not found.</p>"; // start fresh
return ob_get_clean();
}
echo "</div>";
return ob_get_clean();
}
echo renderUser(null); // <p>User not found.</p>
echo "\n";
echo renderUser(['name' => 'Ann']);Output:
<p>User not found.</p>
<div class='card'> <h2>Ann</h2></div>Here ob_get_clean() returns the buffer contents and ends buffering in one step, while ob_clean() is used mid-render to abandon the partially built markup.
ob_clean() vs the related functions
The output-control family has four similar-looking names. The two axes are do you keep the data? and do you keep the buffer?
| Function | Returns the data? | Keeps buffer open? | Sends data to client? |
|---|---|---|---|
ob_clean() | no (discards) | yes | no |
ob_end_clean() | no (discards) | no | no |
ob_get_clean() | yes | no | no |
ob_flush() | no | yes | yes (sends, doesn't discard) |
So the common mistake is using ob_end_clean() when you meant ob_clean(): the former closes the buffer level, so a later echo is no longer buffered and any subsequent ob_* call may warn that no buffer is active.
Gotchas
- Buffering must be active. Calling
ob_clean()with noob_start()in effect returnsfalseand raises a notice. Guard withob_get_level()if you're unsure:if (ob_get_level() > 0) { ob_clean(); }. - It only clears the top buffer. Buffers nest.
ob_clean()affects the innermost (most recently started) buffer, not all of them. - It does not reset headers.
ob_clean()empties output text only; headers you've already queued withheader()are unaffected.
Conclusion
ob_clean() discards the contents of the current output buffer while leaving buffering switched on, making it the right tool for abandoning output you've decided not to send and continuing from a clean slate. Remember the distinction from ob_end_clean() (which also closes the buffer) and from ob_get_clean() (which hands the contents back to you). For an overview of the whole family, see PHP Output Control.