Función ob_list_handlers() de PHP: Todo lo que necesitas saber
Aprende a usar ob_list_handlers() en PHP para obtener la lista de los manejadores de salida registrados actualmente activos.
La función ob_list_handlers() devuelve un array que contiene los nombres de cada manejador de buffer de salida actualmente activo, ordenados desde el buffer más externo hasta el más interno. El almacenamiento en búfer de salida permite a PHP recopilar la salida generada en memoria en lugar de enviarla directamente al navegador; un manejador es el callback opcional que se adjunta a un buffer con ob_start() para transformar esa salida antes de vaciarla. Esta página cubre la sintaxis, el valor de retorno, cómo PHP nombra cada manejador y cuándo resulta útil utilizar ob_list_handlers().
Sintaxis
ob_list_handlers(): arrayLa función no recibe argumentos y devuelve un array de cadenas. Cuando no hay ningún buffer de salida activo, devuelve un array vacío.
Cómo se ven los nombres de los manejadores
Las cadenas que se obtienen no son el contenido del buffer — son etiquetas que identifican cada manejador. La etiqueta depende de cómo se abrió el buffer:
| Cómo se inició el buffer | Nombre en el array |
|---|---|
ob_start() sin callback | "default output handler" |
ob_start('ob_gzhandler') (integrado) | "ob_gzhandler" |
ob_start('my_function') (callback con nombre) | "my_function" |
ob_start(fn($b) => $b) (closure) | "Closure::__invoke" |
Dado que todas las funciones anónimas se reportan como "Closure::__invoke", no es posible distinguir dos closures diferentes a partir de este array — nombra las funciones de tu manejador si necesitas identificarlas más adelante.
Uso básico
Llama a ob_list_handlers() y recorre el resultado. Cuando no hay nada en el buffer, el array está vacío, así que contempla ese caso:
<?php
$handlers = ob_list_handlers();
if (empty($handlers)) {
echo "No output handlers are active.\n";
} else {
foreach ($handlers as $handler) {
echo $handler . "\n";
}
}Sin ningún buffer iniciado, esto imprime:
No output handlers are active.Inspección de manejadores anidados
Los buffers de salida se apilan: cada ob_start() abre un nuevo buffer encima del anterior. ob_list_handlers() refleja toda esa pila, por lo que resulta útil para ver exactamente qué capas están activas.
<?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());Salida:
Array
(
[0] => default output handler
[1] => uppercase_handler
[2] => Closure::__invoke
)El orden coincide con el orden en que se abrieron los buffers: el índice 0 es el buffer más externo (el primero), y el último índice es el más interno (el iniciado más recientemente).
¿Cuándo usaría esto?
ob_list_handlers() es una herramienta de diagnóstico, no algo que se llame en el manejo normal de solicitudes. Recurre a ella cuando necesites:
- Depurar errores de "encabezados ya enviados" o salida inesperada, confirmando qué capas de almacenamiento en búfer están activas.
- Evitar la doble compresión — comprueba si existe
"ob_gzhandler"antes de agregar tu propio manejador gzip, ya que el ajuste INIzlib.output_compressionpuede haber registrado uno ya. - Verificar el comportamiento de frameworks o middleware, ya que muchos frameworks abren sus propios buffers y puede que no sepas qué tan profunda es la pila.
Para contar los buffers activos en lugar de nombrarlos, ob_get_level() devuelve la profundidad directamente:
<?php
ob_start();
ob_start('ob_gzhandler');
echo count(ob_list_handlers()), "\n"; // 2
echo ob_get_level(), "\n"; // 2Salida:
2
2Errores comunes
- Un array vacío es normal. Un retorno de
[]simplemente significa que no hay ningún buffer abierto — no es un error. - Un nombre por buffer. Un buffer iniciado sin callback sigue apareciendo, como
"default output handler"; el nombre refleja el manejador, no si existe un buffer. - Los nombres no son ejecutables. Las cadenas son solo etiquetas. No puedes pasar
"Closure::__invoke"de vuelta aob_start()para recrear el mismo manejador.
Funciones relacionadas
ob_start()— abre un nuevo buffer de salida y opcionalmente adjunta un manejador.ob_get_level()— obtiene el nivel de anidamiento del almacenamiento en búfer de salida.ob_get_contents()— lee el contenido del buffer actual.ob_end_flush()/ob_end_clean()— cierra el buffer más superior.- Control de salida de PHP — descripción general de la familia de almacenamiento en búfer de salida.
Conclusión
ob_list_handlers() te ofrece una instantánea rápida y de solo lectura de la pila de buffers de salida, nombrando cada manejador activo de más externo a más interno. Es más valiosa al depurar problemas de almacenamiento en búfer o antes de registrar un manejador (como gzip) que podría ya estar presente. Combínala con ob_get_level() cuando solo necesites el conteo.