ob_end_flush
Sends the active output buffer's contents onward and turns that buffer off.
ob_end_flush(): bool- Added in PHP 4.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_REMOVABLE flag.
ob_end_flush() calls the active buffer's handler with the PHP_OUTPUT_HANDLER_FINAL flag, sends the handler's return value onward, empties the buffer and removes it from the stack. It is the normal, tidy end of an ob_start() block when you actually want the buffered text delivered.
When to reach for it
Use it when the buffer existed for a reason that has now been satisfied: you needed to be able to call header() after producing markup, you wanted a handler such as a minifier or ob_gzhandler() to process the whole page, or you buffered a section so you could abandon it and then decided to keep it.
What trips people up
"Flush" here means "pass it one level down", not "write it to the socket". Flushing a nested buffer writes its text into its parent buffer, where it stays. Only closing the outermost level actually hands the bytes to the SAPI, and even then the web server may hold them — pair it with flush() if timing matters.
It also flushes even when the buffer was created without PHP_OUTPUT_HANDLER_FLUSHABLE; only a missing PHP_OUTPUT_HANDLER_REMOVABLE flag makes it fail. Since PHP shuts down cleanly by flushing any buffers left open, forgetting the call usually still prints — which is why the bug only shows up once a handler or an error path is involved.
Example
When to use it
- End a page-wide ob_start() block that existed so header() could still be called after markup was produced.
- Release a section you buffered speculatively once you decide to keep it.
- Close a buffer wrapped around a gzip or minification handler so the handler processes the whole document.
Frequently asked questions
What is the difference between ob_flush and ob_end_flush?
ob_flush() sends the buffer's current contents and leaves the buffer open for more output; ob_end_flush() sends them and closes the buffer, dropping the nesting level by one.
Do I have to call ob_end_flush at the end of my script?
No. PHP flushes any buffers still open at shutdown, so output is not lost. Call it explicitly when you need the flush to happen at a specific point, such as before starting a long task.
Why is my output still not visible after ob_end_flush?
Because another buffer is still open below it, or the web server is buffering. Check ob_get_level() and follow up with flush().
More examples
Nested buffers flush into their parent
Prints 'outer inner ' followed by 'all buffers released'. The inner buffer's text lands inside the outer buffer first, which is why the words keep their original order rather than appearing inside out.
<?php
$base = ob_get_level();
ob_start();
echo "outer ";
ob_start();
echo "inner ";
while (ob_get_level() > $base) {
ob_end_flush();
}
echo "\nall buffers released\n";Setting a header after the body was produced
The heading is only emitted at ob_end_flush(). Until then ob_get_length() reports 16, the exact size held back, which is the window in which header() calls are still legal.
<?php
ob_start();
echo "<h1>Report</h1>\n";
$bytes = ob_get_length();
// With the body buffered, headers can still be adjusted here.
ob_end_flush();
echo "released $bytes bytes of markup\n";
Discussion