ob_start
Turns on output buffering so echoed output is held in memory instead of being sent immediately.
ob_start(?callable $callback = null, int $chunk_size = 0, int $flags = PHP_OUTPUT_HANDLER_STDFLAGS): bool- Added in PHP 4.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$callbackoptional | ?callable= null | Optional output handler called when the buffer is flushed, cleaned or closed at script end. It receives the buffer as a string plus an int phase bitmask, and returns the string to output; returning false makes PHP output the buffer unchanged. |
$chunk_sizeoptional | int= 0 | Flush the buffer automatically once it holds this many bytes. 0 buffers everything until the buffer is flushed or closed; 1 flushes after every output operation, which effectively disables buffering. |
$flagsoptional | int= PHP_OUTPUT_HANDLER_STDFLAGS | Bitmask of PHP_OUTPUT_HANDLER_CLEANABLE, PHP_OUTPUT_HANDLER_FLUSHABLE and PHP_OUTPUT_HANDLER_REMOVABLE controlling which operations the buffer allows. The default PHP_OUTPUT_HANDLER_STDFLAGS is all three. |
Return value
boolReturns true on success or false on failure.
Errors
Emits a warning and returns false if the handler cannot be started, for example when the same named handler is already active. Calling ob_start() from inside an output handler causes a fatal error, and a non-callable callback throws a TypeError.
Changelog
- PHP 8.4.0Prior to PHP 8.4.0, the flags parameter could also set output handler status flags. It now only controls which operations (clean, flush, remove) the buffer permits.
ob_start() switches on output buffering. From that point every echo, print, printf or raw HTML outside PHP tags is stored in memory instead of going straight to the browser or terminal. You then decide what happens to it: send it with ob_end_flush(), discard it with ob_end_clean(), or take it as a string with ob_get_clean().
When to reach for it
Use it whenever output is really data: rendering a PHP template file into a string, capturing var_dump() or print_r() for a log, swallowing stray output from a badly behaved library, or delaying output so you can still send headers or a redirect after the page body has been built.
The callback
Passing a callback turns the buffer into a filter. PHP calls it with the buffered string and a phase bitmask (PHP_OUTPUT_HANDLER_START, PHP_OUTPUT_HANDLER_WRITE, PHP_OUTPUT_HANDLER_FLUSH, PHP_OUTPUT_HANDLER_CLEAN, PHP_OUTPUT_HANDLER_FINAL) and prints whatever string you return. Return false to leave the buffer untouched.
Buffers stack
Calls nest. Each ob_start() pushes a new level, and output passes through the handlers from the innermost buffer outwards. ob_get_level() tells you how deep you are, which matters in code paths that return or throw before their matching close call.
Example
When to use it
- Render a PHP template file into a string so it can be emailed, cached to disk or embedded in a JSON response.
- Capture var_dump() or print_r() output into a variable for a log file instead of printing it to the page.
- Buffer a whole page so you can still call header() or redirect after part of the body has been generated.
- Post-process everything a script prints — minify HTML, replace placeholders or append a debug footer — through a single handler.
Frequently asked questions
How do I capture echo output into a variable in PHP?
Call ob_start(), run the code that echoes, then assign ob_get_clean() to a variable — it stops buffering and returns everything that was printed. Use ob_get_contents() instead if you want to read the buffer but keep it open.
Do I have to call ob_end_flush() after ob_start()?
No. PHP flushes any buffers left open when the script ends, so the output is sent anyway. You must close it explicitly with ob_end_clean() or ob_get_clean() if you want the output discarded or returned instead of printed.
What is the difference between ob_start and ob_get_clean?
ob_start() opens a buffer and starts collecting output; ob_get_clean() closes the innermost buffer, discards it and returns what it collected as a string. They are the matching pair for capturing output.
More examples
Filter output with a handler
The handler receives everything echoed while the buffer was open. ob_end_flush() runs stamp_status() over the buffer and prints its return value, so the output is "Report status: FINAL" — the original DRAFT text never reaches the terminal.
<?php
function stamp_status(string $buffer, int $phase = 0): string
{
return str_replace('DRAFT', 'FINAL', $buffer);
}
ob_start('stamp_status');
echo "Report status: DRAFT\n";
ob_end_flush(); // handler runs, then the result is printedNested buffers
Two buffers are open at once. Closing the inner one returns "inner" and leaves the outer buffer collecting, so the final string is "outer INNER". The var_dump prints bool(true), confirming every level opened was closed again.
<?php
$base = ob_get_level();
ob_start();
echo "outer ";
ob_start();
echo "inner";
$inner = ob_get_clean(); // closes only the inner buffer
echo strtoupper($inner);
$outer = ob_get_clean();
echo $outer, "\n";
var_dump(ob_get_level() === $base);Capture var_dump output as a string
var_dump() writes straight to output and has no string-returning variant, so buffering is the standard way to capture it. The first line of the captured text is "array(2) {", showing the dump was collected in $dump rather than printed.
<?php
$data = ['id' => 7, 'tags' => ['a', 'b']];
ob_start();
var_dump($data);
$dump = ob_get_clean();
echo "first line: ", strtok($dump, "\n"), "\n";
echo "total bytes: ", strlen($dump), "\n";
Discussion