Error message

User warning: The following theme is missing from the file system: responsive_green. For information about how to fix this, see the documentation page. in _drupal_trigger_error_with_delayed_logging() (line 1143 of /var/www/moscovie.com/includes/bootstrap.inc).

Add new comment

PHP: Буферизация вывода

Буферизация вывода в 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 '

первый буфер

';
ob_end_flush();

ob_start();
echo '

второй буфер

';
ob_end_сlean();

ob_start();
echo '

третий буфер

';

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

первый буфер

третий буфер

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

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

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

Категория: 

Filtered HTML

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.