Функция PHP ob_end_flush(): всё, что нужно знать
Узнайте, как функция ob_end_flush() в PHP отправляет содержимое буфера вывода и завершает буферизацию. Примеры, сравнение с похожими функциями и типичные ошибки.
Когда PHP захватывает вывод в буфер вместо того, чтобы сразу отправить его браузеру, рано или поздно нужно освободить этот буфер. Функция ob_end_flush() делает именно это: она отправляет содержимое верхнего буфера вывода на следующий уровень (браузеру или во внешний буфер) и затем удаляет этот буфер. На этой странице рассказывается о том, что делает функция, когда её применять, чем она отличается от своих ближайших аналогов и каких подводных камней следует избегать.
Что делает функция ob_end_flush()
ob_end_flush() выполняет два действия над самым внутренним (верхним) активным буфером вывода:
- Сбрасывает буфер — его содержимое передаётся в родительский буфер или отправляется клиенту, если это был последний буфер в стеке.
- Отключает этот буфер, удаляя его из стека буферов.
Функция возвращает true при успехе или false, если активного буфера нет (например, вы вызвали её дважды или ни разу не вызвали ob_start()). При сбое она также выдаёт E_NOTICE.
Буферы образуют стек. Каждый вызов
ob_start()добавляет новый буфер на вершину стека.ob_end_flush()работает только с тем буфером, который находится на вершине, а не со всеми сразу. Узнать количество открытых буферов можно с помощьюob_get_level().
Синтаксис
ob_end_flush(): boolФункция не принимает аргументов и возвращает boolean.
Базовый пример
<?php
ob_start(); // start capturing output
echo "This will be buffered"; // goes into the buffer, not the screen yet
$ok = ob_end_flush(); // send the buffer out, then close it
var_dump($ok); // bool(true)Вывод:
This will be bufferedbool(true)ob_start() открывает буфер, echo помещает данные в него, а ob_end_flush() передаёт текст браузеру и завершает буферизацию. var_dump() выполняется после закрытия буфера, поэтому его вывод отправляется напрямую.
Когда использовать эту функцию?
Буферизация вывода особенно полезна, когда нужно принять решение позже о том, что делать с уже сгенерированным выводом:
- Захват, последующий анализ или изменение — буферизуйте раздел, прочитайте его с помощью
ob_get_contents(), при необходимости измените, затем вызовитеob_end_flush(), чтобы отправить (возможно изменённый) результат. - Отправка заголовков после вывода — пока буферизация активна, ничего не доходит до клиента, поэтому вы можете вызывать
header()илиsetcookie()даже послеechoс разметкой.ob_end_flush()освобождает всё, когда заголовки уже установлены. - Вложенные шаблоны — оборачивайте внутренний буфер, сбрасывайте его во внешний буфер для дальнейшей обработки.
Если вместо этого нужно сохранить захваченный текст в переменной, а не отправлять его, используйте ob_get_clean(). Если нужно отбросить вывод, используйте ob_end_clean().
ob_end_flush() в сравнении с похожими функциями
| Функция | Отправляет буфер? | Оставляет буфер открытым? | Возвращает содержимое? |
|---|---|---|---|
ob_end_flush() | Да | Нет (закрывает) | Нет (возвращает bool) |
ob_get_flush() | Да | Нет (закрывает) | Да (возвращает строку) |
ob_flush() | Да | Да (остаётся открытым) | Нет |
ob_end_clean() | Нет (удаляет) | Нет (закрывает) | Нет |
Простой способ запомнить: flush отправляет, clean удаляет, get_ также возвращает строку, а end_ закрывает буфер вместо того, чтобы оставить его открытым.
Сброс вложенных буферов
Поскольку ob_end_flush() закрывает только один уровень, для полного разворачивания стека нужно вызывать функцию по одному разу для каждого буфера:
<?php
ob_start(); // level 1
echo "outer ";
ob_start(); // level 2
echo "inner";
echo ob_get_level(); // 2 — captured into level 2
ob_end_flush(); // level 2 flushes into level 1
ob_end_flush(); // level 1 flushes to the browserВывод:
outer inner2Внутренний echo и счётчик уровней попадают в буфер 2; первый ob_end_flush() объединяет их с буфером 1, а второй отправляет всё клиенту.
Типичные ошибки
- Вызов при отсутствии активного буфера возвращает
falseи генерирует уведомление. Используйте проверкуif (ob_get_level() > 0), если не уверены, что буфер открыт. - Функция не сбрасывает всё — один вызов закрывает один буфер. Выполняйте цикл до тех пор, пока
ob_get_level()не станет равным0, чтобы развернуть все уровни. - Не путайте с
flush(). Обычныйflush()передаёт буферы записи PHP/SAPI клиенту, но не затрагивает стек буферизации вывода.
Заключение
ob_end_flush() отправляет текущий буфер вывода на следующий уровень и затем закрывает его. Используйте эту функцию, когда вы применяли ob_start() для захвата вывода и теперь хотите его освободить. Помните, что буферы образуют стек, функция работает только с верхним из них, а варианты clean/get_ предлагают возможности удаления и возврата данных, которые могут вам понадобиться.