Управление буфером вывода

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

Функции

bool ob_start ([ callable $output_callback = NULL [, int $chunk_size = 0 [, int $flags = PHP_OUTPUT_HANDLER_STDFLAGS ]]] )

  • Включает буферизацию вывода. Если буферизация вывода активна, вывод скрипта не высылается (кроме заголовков), а сохраняется во внутреннем буфере.
  • Содержимое этого внутреннего буфера может быть скопировано в строковую переменную, используя ob_get_contents(). Для вывода содержимого внутреннего буфера следует использовать ob_end_flush(). В качестве альтернативы можно использовать ob_end_clean() для уничтожения содержимого буфера.
  • Буферы вывода помещаются в стек, то есть допускается вызов ob_start() после вызова другой активной ob_start(). При этом необходимо вызывать ob_end_flush() соответствующее количество раз. Если активны несколько callback-функций, вывод последовательно фильтруется для каждой из них в порядке вложения.

string ob_get_contents ( void )

  • Возвращает содержимое буфера вывода.
  • Вернет содержимое буфера вывода или FALSE, если буферизация вывода не активирована.

int ob_get_length ( void )

  • Возвращает размер в байтах содержимого буфера вывода или FALSE если буферизация не активна.

void ob_clean ( void )

  • Эта функция удаляет содержимое выходного буфера.
  • Эта функция не уничтожает буфер вывода, как это делает ob_end_clean().
  • Буфер вывода должен запускаться функцией ob_start() с флагом PHP_OUTPUT_HANDLER_CLEANABLE. Иначе не сработает ob_clean().

bool ob_end_clean ( void )

  • Удаляет содержимое самого верхнего буфера вывода и отключает эту буферизацию. Если вы хотите использовать содержимое буфера, то вам необходимо вызвать ob_get_contents() перед ob_end_clean(), так как все содержимое буфера удаляется при вызове ob_end_clean().
  • Буфер вывода должен запускаться функцией ob_start() с флагами PHP_OUTPUT_HANDLER_CLEANABLE и PHP_OUTPUT_HANDLER_REMOVABLE. Иначе не сработает ob_end_clean().

ob_get_clean()

  • Получает содержимое текущего буфера и затем удаляет текущий буфер.
  • По сути выполняет ob_get_contents() и ob_end_clean().

void ob_flush ( void )

  • Отправит содержимое буфера вывода (если имеется). Если необходима дальнейшая обработка буфера вывода, то следует вызвать ob_get_contents() перед ob_flush(), так как содержимое буфера будет удалено после вызова ob_flush().

bool ob_end_flush ( void )

  • Отправит содержимое буфера вывода (если оно имеется) и отключит эту буферизацию вывода. Если вы хотите использовать содержимое буфера, то вам необходимо вызвать ob_get_contents() перед ob_end_flush(), т.к. все содержимое буфера удаляется при вызове ob_end_flush().
  • Буфер вывода должен запускаться функцией ob_start() с флагами PHP_OUTPUT_HANDLER_FLUSHABLE и PHP_OUTPUT_HANDLER_REMOVABLE.

Стек буферов

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

Подпись "уровень" - это фактический уровень вложенности буфера. Когда в коде следует инструкция очистить буфер и вывести его содержимое ( например вызов функции ob_end_flush() ), то содержимое буфера выводится внутрь его родительского контейнера. Если родительского контейнера нет, то содержимое выводится в основной поток, т.е. (условно) на экран:

// Буфер верхнего уровня:
ob_start();

ob_start();
echo '<p>вывод второго буфера</p>';
ob_end_flush();

echo '<p>вывод первого буфера</p>';

ob_start();
echo '<p>вывод третьего буфера</p>';
ob_end_flush();

ob_end_flush();

/*
<p>вывод второго буфера</p>
<p>вывод первого буфера</p>
<p>вывод третьего буфера</p>
*/

Обратите внимание: очерёдность вывода сохраняется. Теперь проведём такой эксперимент - уничтожим основной буфер, т.е. тот который находиться на самом верху стека:

// Буфер верхнего уровня:
ob_start();

ob_start();
echo '<p>вывод второго буфера</p>';
ob_end_flush();

echo '<p>вывод первого буфера</p>';

ob_start();
echo '<p>вывод третьего буфера</p>';
ob_end_flush();

// Вот тут мы убили весь вывод.
ob_end_clean();

Теперь мы с вами ничего не увидим, потому что вложенные буферы извлекли своё содержимое в буфер верхнего уровня, а буфер верхнего уровня у нас закрылся функцией ob_end_clean().