W3docs

PHP ob_start() Function: Everything You Need to Know

As a PHP developer, you may need to buffer your output to modify it before sending it to the client. The ob_start() function is a built-in function in PHP that

When PHP runs a script, every echo, print, or block of HTML is normally sent to the client immediately. Output buffering changes that: it holds everything the script would print in an in-memory buffer so you can capture, modify, or discard it before it ever leaves the server. The ob_start() function is the built-in that turns this buffering on.

This chapter explains what ob_start() does, its parameters, how to capture and transform output, the most common real-world use cases, and the gotchas that trip people up.

What is the ob_start() Function?

ob_start() turns on output buffering. While buffering is active, nothing the script prints is sent to the browser. Instead it accumulates in an internal buffer until you explicitly send it (flush), grab it as a string, or clean it.

The one thing buffering does not hold back is HTTP headers. Because the body is no longer sent right away, you can still call functions like header() after you have already echoed output — which is the single most common reason developers reach for ob_start().

Buffers also nest: every call to ob_start() pushes a new buffer onto a stack, and the matching close/flush function pops the top one. You can check how deep the stack is with ob_get_level().

Syntax

ob_start(
    ?callable $callback = null,
    int $chunk_size = 0,
    int $flags = PHP_OUTPUT_HANDLER_STDFLAGS
): bool

Parameters:

  • $callback — Optional. A function that receives the buffer contents (and a status bitmask) and returns the string to actually output. Use it to transform everything the script prints — for example, minifying HTML or gzip-compressing it.
  • $chunk_size — Optional. If greater than 0, the callback is invoked every time the buffer reaches this many bytes, instead of only when the buffer is flushed. 0 (the default) means flush only on completion.
  • $flags — Optional. A bitmask controlling whether the buffer can be cleaned, flushed, and removed. The default PHP_OUTPUT_HANDLER_STDFLAGS allows all three.

Return value: true on success, false on failure.

Basic Usage: Capturing Output

The most common pattern is to start a buffer, print something, then capture it into a variable with ob_get_clean() (which returns the buffer and turns buffering off in one step):

<?php

ob_start();                 // start buffering — nothing is sent yet
echo "Hello, ";
echo "world!";
$output = ob_get_clean();   // grab the buffer as a string, stop buffering

echo strtoupper($output);   // now we control what actually gets sent

Output:

HELLO, WORLD!

Here, the two echo calls never reach the client directly. ob_get_clean() returns "Hello, world!", and only the uppercased version is finally printed. This "capture, then transform" flow is what makes buffering powerful.

Transforming Output with a Callback

Instead of capturing manually, you can pass a callback to ob_start(). PHP runs it over the buffer automatically when the buffer is flushed (here, at the end of the script):

<?php

function addBang(string $buffer): string
{
    return str_replace("world", "World!", $buffer);
}

ob_start("addBang");
echo "hello world";
// buffer is flushed automatically at script end → callback runs

Output:

hello World!

This is exactly how built-in handlers such as ob_gzhandler() work — pass it as the callback and your whole page is gzip-compressed transparently.

Common Use Cases

  • Sending headers after output. Because the body is buffered, you can still call header() or setcookie() after echoing HTML, avoiding the dreaded "headers already sent" warning. See headers_sent().
  • Templating. Capture the rendered HTML of a template file into a string instead of printing it directly, so it can be returned, cached, or wrapped in a layout.
  • Post-processing the whole page. Minify HTML, rewrite URLs, or strip comments via a callback before anything is sent.
  • Compression. Use ob_gzhandler to compress responses without changing your script's echo calls.

You will rarely use ob_start() alone. These functions manage the buffer it creates:

  • ob_get_contents() — Returns the buffer's contents without clearing it.
  • ob_get_clean() — Returns the buffer and turns buffering off.
  • ob_clean() — Discards the buffer's contents but keeps buffering on.
  • ob_end_flush() — Sends the buffer to the client and turns buffering off.
  • ob_end_clean() — Discards the buffer and turns buffering off (sends nothing).
  • ob_get_level() — Returns how many nested buffers are currently active.

For a broader overview, see PHP Output Control.

Common Gotchas

  • Always close what you open. Every ob_start() must be matched by a flush/clean call. An unclosed buffer is flushed automatically at script end, but leaving them open in long scripts can hide output or waste memory.
  • ob_get_clean() returns false if no buffer is active. Calling it without a matching ob_start() gives false, not an empty string.
  • Buffering ≠ infinite headers. Headers are not buffered themselves; only the body is. Once any buffer is flushed to the client, headers are locked in.

Conclusion

ob_start() turns on output buffering so PHP holds the script's output in memory instead of sending it immediately. That lets you capture output into a string, transform it with a callback, send headers after printing, or compress an entire page. Pair it with ob_get_clean() to capture, ob_end_flush() to send, and ob_end_clean() to discard — and remember to always close every buffer you open.

Practice

Practice
What does the 'ob_start()' function do in PHP?
What does the 'ob_start()' function do in PHP?
Was this page helpful?