W3docs

Функция PHP ob_flush(): всё, что нужно знать

Функция ob_flush() отправляет содержимое буфера вывода PHP на следующий уровень, оставляя буферизацию активной для дальнейшей работы.

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

Что делает ob_flush()

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

Signature:  ob_flush(): void
Returns:    nothing (void); emits a warning if no buffer is active
PHP:        4.0+ (return type became void in PHP 8.0)

Две вещи легко перепутать:

  • ob_flush() перемещает данные из буфера PHP, но не гарантирует, что они достигнут браузера. Над ним может быть ещё один буфер, а также собственный буфер записи PHP и буфер веб-сервера.
  • flush() проталкивает буферы записи PHP в сторону клиента. Чтобы байты действительно ушли по сети, обычно нужно вызвать оба в правильном порядке: сначала ob_flush(), затем flush().

Функцию необходимо использовать совместно с ob_start(). Вызов ob_flush() при отсутствии активного буфера вызывает notice/warning и ничего не делает.

Синтаксис

ob_flush();

Функция не принимает аргументов и не возвращает значений.

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

Включите буферизацию, выведите что-нибудь, а затем сбросьте буфер:

<?php

ob_start();              // 1. Enable output buffering
echo "This will be buffered";
ob_flush();              // 2. Flush PHP buffer to the next level
flush();                 // 3. Push it toward the client

Вывод:

This will be buffered

ob_start() открывает буфер, echo захватывается в него, ob_flush() освобождает этот текст, а flush() подталкивает его к браузеру. Важно: буфер остаётся открытым после этого — можно снова делать echo и сбрасывать.

Потоковая передача вывода по частям

Наиболее распространённое реальное применение ob_flush() — отправка вывода кусками, чтобы пользователь видел результаты по мере их появления, а не ждал завершения всего скрипта:

<?php

ob_start();

for ($i = 1; $i <= 5; $i++) {
    echo "Processing item $i\n";
    ob_flush();          // hand this line to the next level
    flush();             // and on toward the browser
    // sleep(1);         // (a real task would do work here)
}

Вывод:

Processing item 1
Processing item 2
Processing item 3
Processing item 4
Processing item 5

На реальном сервере с раскомментированным sleep(1) каждая строка появлялась бы с интервалом в одну секунду, а не всё сразу в конце.

ob_flush() vs. ob_end_flush() vs. ob_get_clean()

Выбор неверной функции сброса — обычная причина ошибок. Они отличаются по двум параметрам: остаётся ли буфер открытым и куда уходит содержимое.

ФункцияОтправляет содержимое?Оставляет буфер открытым?
ob_flush()ДаДа — буферизация продолжается
ob_end_flush()ДаНет — закрывает буфер
ob_get_clean()Нет — возвращает как строкуНет — закрывает буфер

Используйте ob_flush(), когда нужно выдавать прогресс, продолжая буферизацию. Используйте ob_end_flush(), когда работа полностью завершена. Используйте ob_get_clean(), когда нужно захватить содержимое буфера в переменную, а не отправлять его.

Распространённые подводные камни

  • Серверная буферизация всё равно может задерживать вывод. Apache, Nginx (буферизация FastCGI), gzip-сжатие и прокси-серверы могут удерживать сброшенные байты, пока не накопится «достаточно». ob_flush() + flush() управляют только стороной PHP.
  • zlib.output_compression нарушает потоковую передачу. При включённом gzip-сжатии вывода промежуточные сбросы обычно буферизуются для сжатия, поэтому чанки не будут передаваться постепенно. Отключите его для потоковых конечных точек.
  • Нет буфера — предупреждение. Вызов ob_flush() без соответствующего ob_start() вызывает предупреждение. Проверьте активный уровень с помощью ob_get_level(), если не уверены.
  • Буфер очищается. После ob_flush() буфер очищается, поэтому прочитать его предыдущее содержимое уже не получится.
  • Принудительная немедленная очистка глобально. ob_implicit_flush(true) заставляет каждый оператор вывода сбрасываться автоматически, устраняя необходимость вызывать ob_flush() после каждого echo.

Заключение

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

Практика

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