Функция PHP ob_get_level(): всё, что нужно знать
Функция ob_get_level() в PHP возвращает текущий уровень вложенности буферизации вывода. Узнайте, как её использовать.
ob_get_level() возвращает количество активных на данный момент буферов вывода — то есть глубину вложенности буферизации вывода. Буферы вывода в PHP образуют стек: каждый вызов ob_start() помещает новый буфер в стек, а каждый вызов ob_end_* извлекает один из него. ob_get_level() сообщает текущую высоту этого стека.
Это самый безопасный способ узнать «включена ли буферизация вывода?» и «сколько уровней вложенности?» без касания буферизованного содержимого. На этой странице рассматриваются сигнатура функции, возвращаемое значение, принцип работы вложенности и типичные случаи применения.
Синтаксис
ob_get_level(): intФункция не принимает аргументов и возвращает int:
0— буферизация вывода не активна.1— открыт ровно один буфер.2,3, … — столько буферов вложено друг в друга.
Функция никогда не выбрасывает исключений и не производит собственного вывода, поэтому её безопасно вызывать в любом месте.
Простой пример
Если буфер ещё не запущен, уровень равен 0. После одного вызова ob_start() он становится 1:
<?php
echo ob_get_level(); // 0 — nothing buffered yet
ob_start();
echo ob_get_level(); // 1 — one buffer is now active
ob_end_clean();
echo ob_get_level(); // 0 — buffer popped, back to baselineОбратите внимание, что два вызова echo внутри буфера сами захватываются буфером; ob_end_clean() отбрасывает этот захваченный текст, поэтому до браузера доходит только финальный 0. Чтобы видеть промежуточные значения во время разработки, сохраните их предварительно в переменные или используйте ob_get_clean() для освобождения буфера.
Подсчёт вложенных буферов
Поскольку буферы образуют стек, двойной вызов ob_start() даёт уровень 2. Именно это поведение делает ob_get_level() по-настоящему полезным:
<?php
ob_start(); // level 1
ob_start(); // level 2
$level = ob_get_level(); // 2
ob_end_clean(); // level 1
ob_end_clean(); // level 0
echo "Deepest nesting was: {$level}"; // Deepest nesting was: 2Фреймворки, шаблонизаторы и обработчики завершения работы нередко открывают собственные буферы, поэтому на реальном запросе уровень может быть уже 1 или выше до того, как начнёт выполняться ваш код.
Когда это применяется?
-
Защитная очистка. Перед отправкой заголовков или запуском нового буфера освободите все открытые, чтобы случайный вывод не нарушил ответ:
<?php // Discard any buffers a framework or earlier code left open while (ob_get_level() > 0) { ob_end_clean(); } -
Условный сброс. Сбрасывайте буфер только если он действительно активен, избегая предупреждения
ob_end_flush()при его отсутствии:<?php if (ob_get_level() > 0) { ob_end_flush(); } -
Отладка утечек буферов. Запись значения
ob_get_level()в начале и конце запроса помогает обнаружить буфер, который был открыт, но так и не закрыт.
Подводные камни
ob_get_level()не читает и не очищает буфер — для этого используйтеob_get_contents()илиob_get_clean().- Вызов
ob_end_clean()/ob_end_flush()при уровне0вызывает уведомление. Защищайте такие вызовы проверкойob_get_level() > 0, как показано выше. - Высокое значение
zlib.output_compressionили настройки фреймворка могут привести к тому, что уровень будет ненулевым с самой первой строки вашего скрипта — никогда не рассчитывайте на то, что он начинается с0.
Заключение
ob_get_level() сообщает текущую глубину стека буферов вывода PHP: 0 при отключённой буферизации и большее число для каждого вложенного ob_start(). Поскольку функция проверяет стек, не потребляя буферизованное содержимое, она является подходящим инструментом для защиты операций с буферами и для чистого освобождения всех открытых буферов перед отправкой окончательного ответа.