Функция PHP ob_implicit_flush(): всё, что нужно знать
Функция ob_implicit_flush() управляет неявной отправкой выходного буфера в PHP. Узнайте синтаксис, параметры и практические примеры использования.
По умолчанию PHP собирает всё, что выводит скрипт, во внутренний буфер и отправляет это клиенту порциями. Неявная отправка меняет такое поведение: она указывает PHP передавать вывод клиенту после каждого оператора вывода, не дожидаясь завершения скрипта. Функция ob_implicit_flush() — это встроенный переключатель, включающий и отключающий данное поведение. В этой статье рассматриваются синтаксис, параметры, возвращаемое значение, реальные случаи применения и распространённые ловушки.
Что такое функция ob_implicit_flush()?
Функция ob_implicit_flush() переключает неявную отправку для текущего уровня выходного буфера. Когда она включена, PHP ведёт себя так, как если бы ob_flush() вызывался автоматически после каждого echo, print, printf или print_r — вывод немедленно передаётся следующему слою, а не удерживается.
Это наиболее полезно для длительно выполняющихся скриптов, где пользователь должен видеть прогресс по мере его выполнения — например, лог развёртывания, экспорт CSV или индикатор прогресса — вместо того чтобы смотреть на пустую страницу до окончания работы скрипта.
Важно: неявная отправка влияет только на собственный выходной буфер PHP. Веб-серверы Apache, Nginx и PHP-FPM имеют собственные буферы, как и браузер. Чтобы действительно доставить байты пользователю, как правило, всё равно нужен отдельный вызов
flush()и, в идеале, отсутствие буфераob_start(), удерживающего данные.
Синтаксис
ob_implicit_flush(bool $enable = true): voidПараметры
| Параметр | Тип | Описание |
|---|---|---|
$enable | bool | true включает неявную отправку, false — отключает. По умолчанию true. |
Возвращаемое значение
В PHP 8.0 и выше функция возвращает void. В PHP 7.x и ранее она возвращала предыдущее состояние неявной отправки в виде bool. Из-за этого изменения не следует полагаться на возвращаемое значение в коде, который должен работать в разных версиях.
Как использовать функцию ob_implicit_flush()
Типичный шаблон: отключить обычный буфер PHP (или завершить его), включить неявную отправку и вызвать flush() для обхода серверного буфера:
<?php
// Turn off PHP's output buffering for this script so nothing is held back.
while (ob_get_level() > 0) {
ob_end_flush();
}
ob_implicit_flush(true);
for ($i = 1; $i <= 3; $i++) {
echo "Step {$i} done\n";
flush(); // defeat the web server buffer
sleep(1); // simulate slow work
}
echo "All steps finished\n";Каждая строка появляется в браузере примерно через одну секунду, а не все сразу в конце. ob_implicit_flush(true) устраняет необходимость вызывать ob_flush() после каждого echo, а flush() проталкивает данные мимо собственного буфера веб-сервера.
При запуске из командной строки буферных слоёв выше PHP не существует, поэтому вывод уже идёт построчно — это делает CLI удобным местом для проверки логики перед развёртыванием за веб-сервером.
Когда следует использовать эту функцию?
- Потоковый вывод прогресса — задания импорта, пакетная обработка или всё, где строка состояния для каждого элемента поддерживает соединение живым и информирует пользователя.
- Server-Sent Events (SSE) — отправка строк
data:в браузер в режиме реального времени. - Отладка проблем с буферизацией — временное включение помогает точно определить, где зависает вывод.
Как правило, не следует использовать неявную отправку для обычных страниц: отправка вывода одним пакетом эффективнее и позволяет PHP устанавливать заголовки позже в скрипте.
Распространённые ловушки
- Одного этого недостаточно. Буферизация на уровне сервера (и
gzip/mod_deflate) всё равно может удерживать вывод. Для доставки в реальном времени может потребоваться отключить сжатие и вызватьflush(). - Активный буфер
ob_start()имеет приоритет. Если буфер открыт, вывод сначала попадает туда. Завершите его с помощьюob_end_flush()илиob_end_clean()перед использованием неявной отправки. - После отправки нельзя устанавливать заголовки. Как только какой-либо вывод будет отправлен, вызовы
header()завершатся с ошибкой «headers already sent».
Связанные функции
ob_start()— запустить новый выходной буфер.ob_flush()— вручную отправить текущий буфер.flush()— сбросить системные буферы записи ниже PHP.- Обзор управления выводом PHP — вся семья
ob_*в одном месте.
Заключение
Функция ob_implicit_flush() предоставляет простой переключатель, заставляющий PHP немедленно отправлять вывод после каждого оператора, вместо его буферизации. В сочетании с flush() и пониманием серверных буферов она позволяет создавать индикаторы прогресса и потоковые ответы для длительно выполняющихся скриптов. Для обычных страниц оставьте её выключенной и позвольте PHP группировать вывод.