php8.5
Home/ Manual/ reference / outcontrol/ User-Level Output Buffers

User-Level Output Buffers

User-level output buffers can be started, manipulated and terminated from PHP code. Each of these buffers includes an output buffer and an associated output handler function.

User-level output buffers can be started, manipulated and terminated from PHP code. Each of these buffers includes an output buffer and an associated output handler function.

What Output Is Buffered?

PHP's user-level output buffers buffer all output after they are started until they are turned off or the script ends. Output in the context of PHP's user-level output buffer is everything that PHP would display or send back to the browser. In practical terms, output is non-zero length data that is:

Note

Data that is written directly to stdout or passed to an SAPI function with a similar functionality will not be captured by user-level output buffers. This includes writing data to stdout with fwrite() or sending headers using header() or setcookie().

Turning Output Buffering On

Output buffering can be turned on by using the ob_start() function or by setting the output_buffering and output_handler Ini settings. While both can create output buffers, ob_start() is more flexible as it accepts user-defined functions as output handlers and the operations allowed on the buffer (flush, clean, remove) can be set as well. Buffers started with ob_start() will be active from the line the function was called, while those started with output_buffering will be buffering output from the first line of the script.

PHP is also shipped with a built-in "URL-Rewriter" output handler which starts its own output buffer and only allows up to two instances of it running at any time (one for user-level URL-rewriting and one for transparent session id support). These buffers can be started by calling the output_add_rewrite_var() function and/or by enabling the session.use_trans_sid Ini setting.

The bundled zlib extension has its own output buffer which can be enabled by using the zlib.output_compression Ini setting.

Note

While "URL-Rewriter" is special in that it only allows up to two instances of it running at any one time, all user-level output buffers use the same underlying buffers used by ob_start() with their functionality implemented by a custom output handler function. As such, all of their functionality can be emulated by userland code.

Nesting Output Buffers

If there is an output buffer active when a new buffer is started, the new buffer will be nested inside the previously active buffer. The inner buffer will behave the same way regardless whether it is nested but output buffered by it will not be buffered by the outer buffer. Only output flushed by the inner buffer will be buffered by the outer buffer.

Most ob_* functions only work with the active output buffer (the last one started) therefore only the active buffer can be flushed, cleaned and turned off. The functions that work with other buffers are ob_list_handlers() which returns the list of all output handlers in use and ob_get_status() which can return information on the active buffer only or on all buffers in use.

Calling ob_get_level() or ob_get_status() will return the nesting level of the active output buffer.

Caution

The value for identical levels between ob_get_level() and ob_get_status() is off by one. For ob_get_level() the first level is 1, whereas for ob_get_status() the first level is 0.

Buffer Size

Buffer sizes are expressed by integers and represent the number of bytes the buffer can store without flushing. When the size of output in the buffer exceeds the size of the buffer, the contents of the buffer are sent to the output handler, its return value is flushed and the buffer is cleared.

With the exception of "URL-Rewriter", the size of output buffers can be set when the buffer is started. If set to 0, the output buffer is only limited by the memory available to PHP. If set to 1, the buffer is flushed after every block of code producing any non-zero length output.

The size of output buffers can be retrieved by calling ob_get_status().

Output buffers started with ob_start() will have their buffer sizes set to the integer value passed to the function's second chunk_size parameter. If omitted, it is set to 0.

The output buffer started with output_buffering set to "On" will have its buffer size set to 0. If set to an integer than buffer size will correspond to that number.

"URL-Rewriter"'s buffer size is set to 0, therefore it is only limited by the memory available to PHP.

The size of zlib's output buffer is controlled by the zlib.output_compression Ini setting. If set to "On" the buffer size will be "16K"/16384. If set to an integer then buffer size will correspond to that number in bytes.

Operations Allowed On Buffers

The operations allowed on buffers can be controlled by passing one of the buffer control flags to ob_start()'s third flags parameter. If omitted, all operations are allowed by default. If 0 is used instead, the buffer cannot be flushed, cleaned or removed but its contents can still be retrieved.

PHP_OUTPUT_HANDLER_CLEANABLE allows ob_clean() to clean the contents of the buffer.

Warning

The absence of the PHP_OUTPUT_HANDLER_CLEANABLE flag will not prevent ob_end_clean() or ob_get_clean() from clearing the contents of the buffer.

PHP_OUTPUT_HANDLER_FLUSHABLE allows ob_flush() to flush the contents of the buffer.

Warning

The absence of the PHP_OUTPUT_HANDLER_FLUSHABLE flag will not prevent ob_end_flush() or ob_get_flush() from flushing the contents of the buffer.

PHP_OUTPUT_HANDLER_REMOVABLE allows ob_end_clean(), ob_end_flush(), ob_get_clean() or ob_get_flush() to turn off the buffer.

PHP_OUTPUT_HANDLER_STDFLAGS, the combination of the three flags will allow each of the three operations to be performed on the buffer.

Flushing, Accessing And Cleaning Buffer Contents

Flushing sends and discards the contents of the active buffer. Output buffers get flushed when the size of the output exceeds the size of the buffer; the script ends or ob_flush(), ob_end_flush() or ob_get_flush() is called.

Caution

Calling ob_end_flush() or ob_get_flush() will turn off the active buffer.

Caution

Flushing buffers will flush the return value of the output handler which can differ from the contents of the buffer. For example, using ob_gzhandler() will compress the output and flush the compressed output.

The contents of the active buffer can be retrieved by calling ob_get_contents(), ob_get_clean() or ob_get_flush().

If only the length of the buffer's contents are needed, ob_get_length() or ob_get_status() will return the length of the contents in bytes.

Caution

Calling ob_get_clean() or ob_get_flush() will turn off the active buffer after returning the its contents.

The contents of the active buffer can be cleaned by calling ob_clean(), ob_end_clean() or ob_get_clean().

Caution

Calling ob_end_clean() or ob_get_clean() will turn off the active buffer.

Turning Buffers Off

Output buffers can be turned off by calling ob_end_clean(), ob_end_flush(), ob_get_flush() or ob_get_clean().

Warning

Output buffers started without the PHP_OUTPUT_HANDLER_REMOVABLE flag cannot be turned off and may generate an E_NOTICE.

Every output buffer that has not been closed by the end of the script or when exit() is called will be flushed and turned off by PHP's shutdown process. The buffers will be flushed and turned off in reverse order of their starting up. The last buffered started will be first, the first buffer started will be last to be flushed and turned off.

Caution

If flushing of the buffer's contents is not desired, a custom output handler should be used to prevent flushing during shutdown.

Output Handlers

Output handlers are callables associated with output buffers that are invoked by calling ob_clean(), ob_flush(), ob_end_flush(), ob_get_flush(), ob_end_clean(), ob_get_clean() or during PHP's shutdown process.

Note

The shutdown process will flush the return value of the handler.

If omitted or null when starting the output buffer the internal "default output handler" will be used which returns the unmodified contents of the buffer when invoked. Output handlers can be used to return a modified version of the buffer's contents and/or have side-effects (e.g. send headers).

PHP comes with two internal output handlers: "default output handler" and "URL-Rewriter" (which is integrated into its own output buffer and only up to two instances of it can be started).

The bundled extensions include four additional output handlers: mb_output_handler(), ob_gzhandler(), ob_iconv_handler(), ob_tidyhandler().

Working With Output Handlers

When invoked, output handlers are passed the contents of the buffer and a bitmask indicating the status of output buffering.

handler(string $buffer, [int $phase]): string
buffer

Contents of the output buffer.

phase

Bitmask of PHP_OUTPUT_HANDLER_* constants.

Warning

Calling any of the following functions from within an output handler will result in a fatal error: ob_clean(), ob_end_clean(), ob_end_flush(), ob_flush(), ob_get_clean(), ob_get_flush(), ob_start().

Note

If the PHP_OUTPUT_HANDLER_DISABLED of a handler is set, the handler will not be invoked by calling ob_end_clean(), ob_end_flush(), ob_get_clean(), ob_get_flush(), ob_clean(), ob_flush() or during PHP's shutdown process. Prior to PHP 8.4.0, this flag had no effect when calling ob_clean() or ob_flush().

Note

The working directory of the script can change inside the shutdown function under some web servers, e.g. Apache or the built-in web server.

Flags Passed To Output Handlers

The bitmask passed to the second phase parameter of the output handler provides information on the invocation of the handler.

Note

The bitmask can include more than one flag and the bitwise & operator should be used to check whether a flag is set.

Warning

The value of PHP_OUTPUT_HANDLER_WRITE and its alias PHP_OUTPUT_HANDLER_CONT is 0 therefore whether it is set can only be determined by using an equality operator (== or ===).

The following flags are set in a specific phase of the handler's lifecycle: PHP_OUTPUT_HANDLER_START is set when a handler is invoked for the first time. PHP_OUTPUT_HANDLER_FINAL or its alias PHP_OUTPUT_HANDLER_END is set when a handler is invoked for the last time, i.e. it is being turned off. This flag is also set when buffers are being turned off by PHP's shutdown process.

The following flags are set by a specific invocation of the handler: PHP_OUTPUT_HANDLER_FLUSH is set when the handler is invoked by calling ob_flush(). PHP_OUTPUT_HANDLER_WRITE or its alias PHP_OUTPUT_HANDLER_CONT is set when the size of its contents equals or exceeds the size of the buffer and the handler is invoked while the buffer is being automatically flushed. PHP_OUTPUT_HANDLER_FLUSH is set when the handler is invoked by calling ob_clean(), ob_end_clean() or ob_get_clean(). When ob_end_clean() or ob_get_clean() is called, PHP_OUTPUT_HANDLER_FINAL is set as well.

Note

When ob_end_flush() or ob_get_flush() is called, PHP_OUTPUT_HANDLER_FINAL is set but PHP_OUTPUT_HANDLER_FLUSH is not.

Output Handler Return Values

The return value of the output handler is internally coerced into a string following standard PHP type semantics, with two exceptions: arrays and booleans.

Arrays are converted into the string "Array" but the Array to string conversion warning is not triggered.

If the handler returns false the contents of the buffer are returned. If the handler returns true an empty string is returned.

Note

If a handler returns false or throws an exception its PHP_OUTPUT_HANDLER_DISABLED status flag is set.

Exceptions Thrown In Output Handlers

If an uncaught exception is thrown in an output handler the program terminates and the handler is invoked by the shutdown process after which the "Uncaught Exception" error message is flushed.

If the uncaught exception is thrown in a handler invoked by ob_flush(), ob_end_flush() or ob_get_flush(), the contents of the buffer are flushed before the error message.

If an uncaught exception is thrown in an output handler during shutdown, the handler is terminated and neither the contents of the buffer nor the error message is flushed.

Note

If a handler throws an exception its PHP_OUTPUT_HANDLER_DISABLED status flag is set.

Errors Raised In Output Handlers

If a non-fatal error is raised in an output handler the program continues execution.

If the non-fatal error is raised in a handler invoked by ob_flush(), ob_end_flush() or ob_get_flush(), the buffer flushes certain data depending on the return value of the handler. If the handler returns false the buffer and the error message are flushed. If the returns anything else the handler return value is flushed but not the error message.

Note

If a handler returns false its PHP_OUTPUT_HANDLER_DISABLED status flag is set.

If a fatal error is raised in an output handler the program terminates and the handler is invoked by the shutdown process after which the error message is flushed.

If the fatal error is raised in a handler invoked by ob_flush(), ob_end_flush() or ob_get_flush(), the contents of the buffers are flushed before the error message.

If a fatal error is raised in an output handler during shutdown the program terminates without flushing the buffer or the error message.

Output In Output Handlers

In specific circumstances, output produced in the handler is flushed along with the contents of the buffer. This output is not appended to the buffer and is not part of the string returned by ob_get_flush().

During flush operations (calling ob_flush(), ob_end_flush(), ob_get_flush() and during shutdown) if the return value of a handler is false the contents of the buffer are flushed followed by the output. If the handler is not invoked during shutdown the handler throwing an exception or exit() being called results in the same behavior.

Note

If a handler returns false its PHP_OUTPUT_HANDLER_DISABLED status flag is set.

Output Handler Status Flags

The handler status flags of the buffer's flags bitmask are set every time to the output handler is invoked and are part of the flags returned by ob_get_status(). If the handler successfully executes and does not return false, PHP_OUTPUT_HANDLER_STARTED and PHP_OUTPUT_HANDLER_PROCESSED is set. If the handler returns false or throws an exception while executing, PHP_OUTPUT_HANDLER_STARTED and PHP_OUTPUT_HANDLER_DISABLED is set.

Note

If the PHP_OUTPUT_HANDLER_DISABLED of a handler is set, the handler will not be invoked by calling ob_end_clean(), ob_end_flush(), ob_get_clean(), ob_get_flush(), ob_clean(), ob_flush() or during PHP's shutdown process. Prior to PHP 8.4.0, this flag had no effect when calling ob_clean() or ob_flush().

Source: reference/outcontrol/user-level-output-buffers.xml · from the official PHP manual (php/doc-en)