W3docs

Функция 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-обработчика, так как настройка INI zlib.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(), если вам нужно только количество буферов.

Практика

Практика
Какова функциональность ob_list_handlers() в PHP?
Какова функциональность ob_list_handlers() в PHP?
Was this page helpful?