W3docs

PHP ob_list_handlers() Function: Everything You Need to Know

As a PHP developer, you may need to get a list of the registered output handlers. The ob_list_handlers() function is a built-in function in PHP that allows you

The ob_list_handlers() function returns an array containing the names of every output buffer handler that is currently active, ordered from the outermost buffer to the innermost. Output buffering lets PHP collect generated output in memory instead of sending it straight to the browser; a handler is the optional callback you attach to a buffer with ob_start() to transform that output before it is flushed. This page covers the syntax, return value, how PHP names each handler, and when reaching for ob_list_handlers() actually helps.

Syntax

ob_list_handlers(): array

The function takes no arguments and returns an array of strings. When no output buffer is active, it returns an empty array.

What the Handler Names Look Like

The strings you get back are not the buffer's contents — they are labels that identify each handler. The label depends on how the buffer was opened:

How the buffer was startedName in the array
ob_start() with no callback"default output handler"
ob_start('ob_gzhandler') (built-in)"ob_gzhandler"
ob_start('my_function') (named callback)"my_function"
ob_start(fn($b) => $b) (closure)"Closure::__invoke"

Because anonymous functions all report as "Closure::__invoke", you cannot tell two different closures apart from this array — name your handler functions if you need to identify them later.

Basic Usage

Call ob_list_handlers() and loop over the result. When nothing is buffered the array is empty, so guard for that case:

<?php

$handlers = ob_list_handlers();

if (empty($handlers)) {
    echo "No output handlers are active.\n";
} else {
    foreach ($handlers as $handler) {
        echo $handler . "\n";
    }
}

With no buffer started, this prints:

No output handlers are active.

Inspecting Nested Handlers

Output buffers stack: each ob_start() opens a new buffer on top of the previous one. ob_list_handlers() reflects that whole stack, so it is handy for seeing exactly what is layered together.

<?php

function uppercase_handler(string $buffer): string
{
    return strtoupper($buffer);
}

ob_start();                       // default buffer, no callback
ob_start('uppercase_handler');    // named callback
ob_start(function ($buffer) {     // anonymous callback
    return trim($buffer);
});

print_r(ob_list_handlers());

Output:

Array
(
    [0] => default output handler
    [1] => uppercase_handler
    [2] => Closure::__invoke
)

The order matches the order the buffers were opened: index 0 is the outermost (first) buffer, and the last index is the innermost (most recently started) one.

When Would I Use This?

ob_list_handlers() is a diagnostic tool, not something you call in normal request handling. Reach for it when you need to:

  • Debug "headers already sent" or unexpected output by confirming which buffering layers are in play.
  • Avoid double-compression — check for "ob_gzhandler" before adding your own gzip handler, since the zlib.output_compression INI setting may already register one.
  • Verify framework or middleware behavior, since many frameworks open their own buffers and you may not know how deep the stack is.

To count active buffers instead of naming them, ob_get_level() returns the depth directly:

<?php

ob_start();
ob_start('ob_gzhandler');

echo count(ob_list_handlers()), "\n"; // 2
echo ob_get_level(), "\n";            // 2

Output:

2
2

Common Gotchas

  • Empty array is normal. A return of [] simply means no buffer is open — it is not an error.
  • One name per buffer. A buffer started without a callback still appears, as "default output handler"; the name reflects the handler, not whether a buffer exists.
  • Names are not callable. The strings are labels only. You cannot pass "Closure::__invoke" back to ob_start() to recreate the same handler.

Conclusion

ob_list_handlers() gives you a quick, read-only snapshot of the output-buffer stack, naming each active handler from outermost to innermost. It is most valuable while debugging buffering issues or before registering a handler (such as gzip) that might already be present. Pair it with ob_get_level() when you only need the count.

Practice

Practice
What is the functionality of ob_list_handlers() in PHP?
What is the functionality of ob_list_handlers() in PHP?
Was this page helpful?