Главная страница » Статьи и уроки » PHP статьи » PHP: Буферизация вывода
Опрос
Какие статьи добавлять?
Выделенные и виртуальные серверы в Европе

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

Автор: administrator Дата: 20-12-2014, 01:11 Категория: Статьи и уроки / 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 из любого места в скрипте.
  • Стартовать сессию в любой момент.
  • Сжимать данные, перед отправкой их пользователю.

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


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

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

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

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

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

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

ob_end_flush() - Закрывает буфер и отправляет данные.
ob_end_clean() - Закрывает буфер без отправки данных.

Все содержимое, которое выводиться в тот момент, когда буфер открыт попадает в буфер и никуда не отсылается.
Например:
<?php
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().

Ссылка на оригинал статьи php-zametki.ru
  • Не нравится
  • 0
  • Нравится
Просмотров: 3 011 Напечатать Жалоба
Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь. Мы рекомендуем Вам зарегистрироваться либо зайти на сайт под своим именем.
Написать комментарий
Ваше Имя:
Ваш E-Mail:
  • bowtiesmilelaughingblushsmileyrelaxedsmirk
    heart_eyeskissing_heartkissing_closed_eyesflushedrelievedsatisfiedgrin
    winkstuck_out_tongue_winking_eyestuck_out_tongue_closed_eyesgrinningkissingstuck_out_tonguesleeping
    worriedfrowninganguishedopen_mouthgrimacingconfusedhushed
    expressionlessunamusedsweat_smilesweatdisappointed_relievedwearypensive
    disappointedconfoundedfearfulcold_sweatperseverecrysob
    joyastonishedscreamtired_faceangryragetriumph
    sleepyyummasksunglassesdizzy_faceimpsmiling_imp
    neutral_faceno_mouthinnocent
Код: Кликните на изображение чтобы обновить код, если он неразборчив
Введите код: