Output buffering php.ini

Функция PHP flush

void flush (void)

Очищает буфер вывода PHP и всё используемое PHP (CGI, web-сервер и т.д.). Она активно пытается выдать весь вывод в браузер пользователя.

Примечание: flush() не действует на схему буферизации вашего web-сервера или браузера — на стороне клиента.

Некоторые серверы, особенно под Win32, будут, тем не менее, продолжать буферизовать вывод вашего скрипта, пока он не закончит работу перед передачей результатов в браузер.

Серверные модули для Apache, вроде mod_gzip, могут сами выполнять буферизацию, что не даст немедленной пересылки данных из функции flush() клиенту.

Даже браузер может буферизовать свой ввод до отображения. Netscape, например, буферизует текст, пока не получит end-of-line или начало тэга, и не будет отображать таблицы, пока не увидит тэга </table> самой внешней таблицы.

Некоторые версии Microsoft Internet Explorer начинают отображать страницу только после получения 256 байт вывода, поэтому вам может понадобиться отправить дополнительные пробелы перед очисткой, чтобы такие браузеры вывели страницу.

Страница 1 из 4

Буферизация вывода в PHP это довольно полезная штука, если уметь ею пользоваться. Скажите сколько раз вы видели ошибки типа:

Warning: Cannot modify header information — headers already sent by (output started at …)

Как правило подобное случается, если вы хотите отправить куки, или выполнить операции, которые способствуют их отправке, или иные операции способствующие отправке заголовков, например запуск сессии или применение функции header или подобных. Или ваш файл в кодировке юникод и в самом его начале притаилась BOM — метка порядка байтов. Это подлющая штука есть неразрывный пробел с нулевой шириной. Смотрим под заголовком "Порядок байтов".

Всё очень просто: По — умолчанию никакой буферизации вывода нет ( если, конечно вы не нашаманили в файле php.ini и не присвоили директиве output_buffering значение On ) и PHP отсылает данные юзеру, сразу, как только они готовы. Согласно протоколу HTTP, сервер в ответ на запрос пользователя, должен сначала отправить ему служебные заголовки, а уже после, тело страницы. А тут внезапно, в коде вы опять пытаетесь заставить его отправить HTTP — заголовки, вызывая, скажем функцию session_start() — после удачной авторизации… Ясен пень — повторная отправка заголовков запрещена, HTTP — протокол так не работает! Но что ж делать то? Если после вывода на странице, нужно ещё и сессию стартануть и кУку поставить? — Вспоминаем про буферизацию вывода.

Возможности при буферизации

Используя буферизацию вывода мы можем:

  • Посылать cookie из любого места в скрипте.
  • Стартовать сессию в любой момент.
  • Сжимать данные, перед отправкой их пользователю.

Сжатие дополнительно нагружает процессор, тем не менее объем трафика на одну страницу уменьшится примерно процентов на сорок, а это значит, что сервер потратит меньше времени на пересылку данных по сети. Величина сжатия зависит от многих факторов, например картинки сжимаются хуже чем текст.

Что происходит при буферизации?

При буферизации вывода, механизм PHP складывает в стопку весь вывод скрипта, паралельно формируя пакет HTTP — заголовков, в том числе, добавляя туда и заголовки "cookie" и любые другие, которые получатся в результате работы вашего скрипта. А потом, когда скрипт отработал он берёт и отправляет всё это клиенту в правильном порядке: сначала заголовки, а потом страницу — результат работы скрипта.

Как включить буферизацию вывода?

Первый способ это если сервак ваш, или у вас просто есть доступ к файлу php.ini ( как я писал выше ) ищем в нём директиву output_buffering и присваиваем ей значение On. Это включит буферизацию для всех скриптов.

Второй способ это использовать функцию ob_start() в скрипте, вывод которого нам нужно буферизовать. Этот способ предпочтительней — вы получите большую гибкость/контроль в работе, а так же лучшую переносимость.

На мой взгляд довольно удобно рассматривать буферизацию вывода, в виде неких контейнеров — буферов. Так проще понять их работу.

Итак, открыть такой контейнер — буфер можно лишь одной функцией ob_start(), а вот закрыть этот самый буфер можно двумя функциями: ob_end_flush() и ob_end_clean()

ob_end_flush()

Закрывает буфер и отправляет данные.

ob_end_clean()

Закрывает буфер без отправки данных.

Все содержимое, которое выводиться в тот момент, когда буфер открыт попадает в буфер и никуда не отсылается. Например:

ob_start(); echo ‘<p>первый буфер </p>’; ob_end_flush(); ob_start(); echo ‘<p>второй буфер </p>’; ob_end_сlean(); ob_start(); echo ‘<p>третий буфер </p>’;

Этот скрипт выведет результат:

<p>первый буфер </p> <p>третий буфер </p>

Разберемся что произошло. Мы создали три буфера. Строки 1-3 — это первый. Он закрыт функцией ob_end_flush() — его вывод мы можем наблюдать в результате.

Второй буфер — это строки 5-7. Он закрыт с помощью функции ob_end_clean() — поэтому его вывод пропал безследно.

И третий буфер — это строки 9-10. Он у нас не закрыт никак! — Шозанах? — спросите вы ..? Всё просто — по окончанию сценария, PHP автоматом закрывает все буферы так, как будто они были закрыты функцией ob_end_flush().

Предыдущая —

Для чего нужна буферизация

Ранее, изучая работу с заголовками HTTP-сообщений и cookie, мы заостряли внимание на одной особенности. Функции, обрабатывающие их, можно использовать только в том случае, если пользователю не было отправлено никаких данных. Это означает, что любой вывод информации с помощью echo, print и т.п. сделает невозможным дальнейшее формирование заголовков и установку cookie.

PHP позволяет решить эту проблему с помощью буферизации вывода. Буфер можно воспринимать как временное хранилище для накопления информации. Таким образом, приложение получает возможность выполнить свою логику, сохраняя выходные данные. По окончании работы оно сформирует заголовки, достанет данные из буфера и отправит всё это пользователю.

Заметка
Буферизация также является гибким инструментом контроля выводимой информации. Приложение может работать с несколькими буферами, а также согласно условиям сбрасывать одни из них и показывать пользователю другие. Всё это будет рассмотрено в следующих уроках.

Использование буфера вывода

PHP позволяет использовать буферизацию двумя способами: с помощью специальных функций и за счет конфигурации php.ini. Если вы хотите включить буферизацию для всех файлов по умолчанию, установите в php.ini следующую опцию «output_buffering=On».

Ручное управление буферами вывода данных происходит с использованием ряда функций. ob_start() отвечает за создание нового буфера. Весь вывод с использованием echo или print, идущий сразу за ob_start() будет сохранен для дальнейшего обращения. Функция возвращает true в случае успеха и false, если произошла ошибка.

Вывод данных, записанных в буфер, осуществляется с помощью ob_flush(). Вы также можете уничтожить информацию без её показа за счет функции ob_clean().

Очень важной особенностью ob_flush() и ob_clean() является то, что они не уничтожают хранилище. То есть после очистки или вывода данных буфер можно использовать повторно.

Также существуют функции ob_end_flush() и ob_end_clean(). Они обладают аналогичным поведением с одним лишь отличием — буфер вывода данных уничтожается после вызова. Чтобы продолжить дальнейшее сохранение вывода нужно снова использовать функцию ob_start().

//Записываем простую строку в буфер if (ob_start()) {     echo ‘Привет из буфера!’;     ob_end_flush();     /*     * Результат:     * Привет из буфера! */ } else {     echo ‘Невозможно создать буфер вывода’; } //Пример очистки и перезаписывания if (ob_start()) {     echo ‘Привет из буфера!’;     ob_clean();     echo ‘Новое приветствие!’;     ob_end_flush();     /*     * Результат:     * Новое приветствие! */ } else {     echo ‘Невозможно создать буфер вывода’; }

.

Добавить комментарий

Закрыть меню