W3docs

Функция PHP flush(): немедленная отправка вывода в браузер

Узнайте, как PHP flush() отправляет буферизованный вывод в браузер немедленно, чем отличается от ob_flush() и когда её использовать.

По умолчанию PHP собирает текст, который выводит ваш скрипт (с помощью echo, print и т. д.), и отправляет его в браузер порциями — зачастую лишь после завершения скрипта. Встроенная функция flush() позволяет передать всё уже произведённое на данный момент прямо сейчас, чтобы пользователь видел частичный вывод ещё до того, как страница полностью сформирована. На этой странице объясняется, что делает flush(), чем она отличается от ob_flush(), какие буферы находятся между вашим скриптом и браузером, и когда её применение действительно помогает.

Что делает функция flush()

flush(): void

flush() просит PHP передать любой удерживаемый вывод нижестоящему слою — SAPI и веб-серверу. Функция не принимает аргументов и ничего не возвращает. Типичный сценарий использования — длительный скрипт, который должен отображать прогресс (строку лога, счётчик), а не заставлять пользователя смотреть на пустую страницу до завершения всех операций.

Два важных ограничения:

  • flush() не влияет на собственный слой буферизации вывода PHP (тот, что запускается с помощью ob_start()). Если буферизация вывода активна, текст по-прежнему заперт в буфере PHP, и flush() нечего отправлять. Сначала необходимо освободить этот слой с помощью ob_flush() или ob_end_flush().
  • flush() не может переопределить буферизацию, выполняемую веб-сервером или прокси (Apache mod_deflate, Nginx proxy_buffering, FastCGI, gzip). Они всё равно могут удерживать данные, пока не решат их отправить.

Базовый пример

Если буферизация вывода PHP не включена, одного flush() достаточно для отправки текущего вывода:

<?php
echo "Starting a slow task...\n";
flush();        // send the line above to the browser now

sleep(2);       // pretend we are doing real work

echo "Done!\n";
?>

Без вызова flush() пользователь обычно увидит обе строки вместе — через 2 секунды. С ним строка "Starting a slow task..." может появиться немедленно.

flush() и ob_flush()

Именно здесь чаще всего возникает путаница. PHP может использовать два отдельных буфера, и каждая функция *flush работает с разным из них:

ФункцияОчищаемый буфер
ob_flush()Буфер управления выводом PHP (созданный ob_start()) → перемещает данные в буфер SAPI
flush()Буфер SAPI / записи → перемещает данные в направлении браузера

Когда буферизация вывода включена, нужны обе функции — по порядку: сначала ob_flush(), чтобы освободить буфер PHP, затем flush(), чтобы продвинуть данные дальше:

<?php
ob_start();             // turn on PHP output buffering
echo "Buffered text\n";

ob_flush();             // PHP buffer -> SAPI buffer
flush();                // SAPI buffer -> browser
?>

Если изменить порядок или пропустить ob_flush(), текст так и останется внутри PHP. Если вы хотите, чтобы PHP автоматически выполнял flush после каждого echo, см. ob_implicit_flush().

Почему это часто «не работает»

Надёжная потоковая передача вывода сложнее, чем вызов одной функции, потому что несколько слоёв выполняют буферизацию независимо:

  • gzip / сжатиеzlib.output_compression и Apache mod_deflate должны накопить достаточное количество байт перед отправкой. Для ответов, которые вы хотите передавать потоком, отключите сжатие.
  • Буферизация веб-сервера / прокси — Nginx (proxy_buffering on), FastCGI и балансировщики нагрузки обычно повторно буферизуют ответ.
  • Отрисовка браузером — некоторые браузеры ждут минимального количества байт перед отрисовкой; добавление дополнительных данных может принудить к более ранней отрисовке.

Из-за всего этого flush() лучше воспринимать как подсказку, а не гарантию. Для современных задач потоковой передачи (server-sent events, чанкованные API) настройте сервер явно, а не полагайтесь только на flush().

Связанные функции вывода

  • ob_flush() — очистить буфер управления выводом PHP.
  • ob_end_flush() — очистить буфер и отключить буферизацию вывода.
  • ob_get_flush() — вернуть содержимое буфера и очистить его.
  • PHP Output Control — обзор того, как слои буферизации взаимодействуют друг с другом.
  • fflush() — сбросить буферизованные записи в открытый файл (не в браузер).

Заключение

flush() принудительно отправляет уже произведённый PHP вывод в направлении браузера, не дожидаясь завершения скрипта. Помните, что функция затрагивает только буфер SAPI/записи: при активном ob_start() сначала необходимо вызвать ob_flush(), и даже в этом случае веб-сервер или слой сжатия может задержать доставку. При понимании этих ограничений flush() — удобный инструмент для потоковой передачи прогресса из длительных скриптов.

Практика

Практика
Что делает функция PHP flush()?
Что делает функция PHP flush()?
Was this page helpful?