Функция ob_list_handlers() в PHP: всё что нужно знать
Функция ob_list_handlers() в PHP возвращает массив имён всех активных обработчиков буферизации вывода. Узнайте синтаксис и примеры использования.
Функция ob_list_handlers() возвращает массив, содержащий имена всех активных обработчиков буферов вывода, упорядоченных от внешнего буфера к внутреннему. Буферизация вывода позволяет PHP собирать генерируемый вывод в памяти вместо немедленной отправки в браузер; обработчик — это необязательный обратный вызов, который вы присоединяете к буферу с помощью ob_start(), чтобы преобразовать вывод перед его отправкой. На этой странице рассматриваются синтаксис, возвращаемое значение, правила именования обработчиков в PHP и случаи, когда ob_list_handlers() действительно полезна.
Синтаксис
ob_list_handlers(): arrayФункция не принимает аргументов и возвращает массив строк. Если ни один буфер вывода не активен, она возвращает пустой массив.
Как выглядят имена обработчиков
Возвращаемые строки — это не содержимое буфера, а метки, идентифицирующие каждый обработчик. Метка зависит от того, как был открыт буфер:
| Способ открытия буфера | Имя в массиве |
|---|---|
ob_start() без обратного вызова | "default output handler" |
ob_start('ob_gzhandler') (встроенный) | "ob_gzhandler" |
ob_start('my_function') (именованный обратный вызов) | "my_function" |
ob_start(fn($b) => $b) (замыкание) | "Closure::__invoke" |
Поскольку все анонимные функции отображаются как "Closure::__invoke", по этому массиву нельзя отличить два разных замыкания друг от друга — именуйте функции-обработчики, если впоследствии вам нужно их идентифицировать.
Базовое использование
Вызовите ob_list_handlers() и переберите результат. Если буферизации нет, массив пуст, поэтому учитывайте этот случай:
<?php
$handlers = ob_list_handlers();
if (empty($handlers)) {
echo "No output handlers are active.\n";
} else {
foreach ($handlers as $handler) {
echo $handler . "\n";
}
}Если ни один буфер не открыт, вывод будет следующим:
No output handlers are active.Просмотр вложенных обработчиков
Буферы вывода образуют стек: каждый вызов ob_start() открывает новый буфер поверх предыдущего. Функция ob_list_handlers() отражает весь этот стек, что позволяет точно видеть, какие слои активны.
<?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());Вывод:
Array
(
[0] => default output handler
[1] => uppercase_handler
[2] => Closure::__invoke
)Порядок соответствует порядку открытия буферов: индекс 0 — самый внешний (первый) буфер, последний индекс — самый внутренний (открытый последним).
Когда это использовать?
ob_list_handlers() — диагностический инструмент, а не то, что используется в обычной обработке запросов. Обращайтесь к ней, когда нужно:
- Отладить ошибку «headers already sent» или неожиданный вывод — убедиться, какие слои буферизации активны.
- Избежать двойного сжатия — проверить наличие
"ob_gzhandler"перед добавлением собственного gzip-обработчика, так как настройка INIzlib.output_compressionможет уже зарегистрировать его. - Проверить поведение фреймворка или промежуточного слоя — многие фреймворки открывают собственные буферы, и глубина стека может быть неочевидной.
Чтобы подсчитать активные буферы без их именования, используйте ob_get_level(), который возвращает глубину стека напрямую:
<?php
ob_start();
ob_start('ob_gzhandler');
echo count(ob_list_handlers()), "\n"; // 2
echo ob_get_level(), "\n"; // 2Вывод:
2
2Распространённые ошибки
- Пустой массив — это нормально. Возврат
[]просто означает, что ни один буфер не открыт — это не ошибка. - Одно имя на буфер. Буфер, открытый без обратного вызова, всё равно отображается как
"default output handler"; имя отражает обработчик, а не факт существования буфера. - Имена не являются вызываемыми. Строки — это только метки. Нельзя передать
"Closure::__invoke"обратно вob_start()для воссоздания того же обработчика.
Связанные функции
ob_start()— открыть новый буфер вывода и при необходимости присоединить обработчик.ob_get_level()— получить уровень вложенности буферизации вывода.ob_get_contents()— прочитать содержимое текущего буфера.ob_end_flush()/ob_end_clean()— закрыть верхний буфер.- Управление выводом в PHP — обзор семейства функций буферизации вывода.
Заключение
ob_list_handlers() даёт быстрый снимок стека буферов вывода только для чтения, называя каждый активный обработчик от внешнего к внутреннему. Она наиболее полезна при отладке проблем с буферизацией или перед регистрацией обработчика (например, gzip), который может уже присутствовать. Используйте её вместе с ob_get_level(), если вам нужно только количество буферов.