Перейти к содержимому

Ob start php что это

  • автор:

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_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().

Повторное использование буферов

Функции ob_end_flush() и ob_end_clean() дополняются функциями: ob_flush() и ob_clean() — они делают то же самое, но не закрывают буфер вывода. Верхний пример с их применением может выглядеть так:

ob_start(); echo '

первый

'; ob_flush(); echo '

второй

'; ob_сlean(); echo '

третий

';

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

первый буфер

третий буфер

Смотрим сверху вниз. На этот раз содержимое выводится так же строка 1-3, но буфер не закрывается, затем буфер просто чистится (строа 5) без вывода содержимого, оставаясь открытым, и наконец буфер автоматом закрывается, а содержимое выводится, так как подошёл конец скрипта. Такой подход даст 60% прирост производительности, по сравнению с предыдущим, за счёт того, что мы избегаем лишних открытий/закрытий буферов.

Стек буферов

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

Стек буферов вывода

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

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

вывод второго буфера

'; ob_end_flush(); echo '

вывод первого буфера

'; ob_start(); echo '

вывод третьего буфера

'; ob_end_flush(); ob_end_flush();

вывод второго буфера

вывод первого буфера

вывод третьего буфера

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

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

вывод второго буфера

'; ob_end_flush(); echo '

вывод первого буфера

'; ob_start(); echo '

вывод третьего буфера

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

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

Главное помнить, что буферы вывода работают в стеке, и всё будет ок.

Чтение буферов вывода

Буфер вывода — штука двунаправленная, т.е. в него можно как писать (ударение на втором слоге! ), так и читать из него. Читать можно в переменную. Сделать это позволяет функция ob_get_contents()

Эта функция не принимает параметров, и возвращает всё содержимое последнего открытого буфера:

ob_start(); echo 'Это какой то текст. много текста. '; // Получаем содержимое буфера в переменную: $content = ob_get_contents(); // Чистим бфер ob_end_clean(); // Пишем данные в файл: file_put_contents('/php-nachinayushhim/93-buferizaciya-vyvoda.html/somefile.txt', $content);

Этот скрипт рассматривает выводимые данные, как сверх оперативную память и сохраняет их в файл, а не выводит пользователю.

Другие ob — функции

У механизма буферизации вывода есть ещё несколько полезных функций:

Не принимает никаких параметров, возвращает число — количество байт информации, хранимой в буфере. Бывает полезна, например при передаче HTTP — заголовка Contetnt-length.

Не принимает никаких параметров, возвращает число — уровень вложенности буфера. Вернёт 0, если вызвана вне какого — либо буфера. Бывает полезна, при реализации рекурсивного закрытия буферов, с передачей или без передачи данных в случае возникновения ошибки.

Не принимает никаких параметров, возвращает массив, содержащий дескрипторы вывода, которые работают на данный момент. Если буферизация включена — вернёт массив, в котором будет дескриптор по-умолчанию, если используется gzip сжатие буфера (об этом позже) то получим дескриптор «ob_gzhandler», а если используется замена URL то получим «URL-Rewriter».

Отправка выходных данных

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

for($i = 1; $i < 11; $i++ ) < sleep(1); echo '

Это очередное обновление данных № '.$i.'

' ; flush(); >

Это очередное обновление данных № 1

Это очередное обновление данных № 2

.

Это очередное обновление данных № 10

При работе этого скрипта данные к клиенту будут уходить частями, с интервалом в 1 сек. И клиент в реальном времене будет видеть, как у него появляются новые данные.

В IE есть некий механизм «оптимизации» который отображает страницу только после получения первых 256 байт информации! Независимо от применения вами функции flush(). Так что имейте ввиду с «ишаком», как всегда могут быть проблемы, если ваш скрипт отправляет клиенту меньше 256 символов ( или примерно 128 символов кирилицы в юникоде ) .

Функция ob_implicit_flush() — избавляет вас от вызова каждый раз функции flush():

ob_implicit_flush(); for($i = 1; $i < 11; $i++ ) < sleep(1); echo '

Это очередное обновление данных № '.$i.'

' ; >

Этот скрипт даст тот же эффект, что и скрипт выше.

Сжатие выходных данных

Для того чтобы сжать буфер вывода нужно передать функции ob_start() параметр — имя функции — компрессора, например ob_gzhandler.При этом будет выполнена проверка поддержки сжатия и если такая поддержка есть, то данные будут сжиматься:

// Здесь мы включили сжатие буфера: ob_start('ob_gzhandler'); echo 'Contrary . section'; ob_end_flush();

Результат обведён красным:

Сжатие буфера вывода

А вот результат без сжатия вывода:

Без сжатия вывода

Сжатие работает только применительно к HTML — коду, к картинкам и прочему это не относится. Учитывайте это. А ещё PHP позволяет сжимать только один буфер вывода, так как содержимое должно сжиматься всё и сразу. Имейте это ввиду, если вы используете стек буферов вывода.

Переписывание URL

Скажу сразу что к ЧПУ ссылкам и к mod_rewrite данные возможности не имеют никакого отношения, но тем не менее позволяют вытворятьинтересные штуки.

output_add_rewrite_var( ‘name’, ‘value’ )

Эта функция принимает два параметра, первый это имя переменной, а второй это значение этой переменной. Эта пара ключ-значение добавиться ко всем URL, формам и атрибутам SRC — элементов FRAME, в виде GET — переменных строки запроса. К формам добавятся скрытые поля с соответствующими значениями. В общем проще показать на примере:

ob_start(); output_add_rewrite_var('somevar', 'someval'); echo ' 
'; echo 'LINK'; ob_end_flush();

Выдаст такой HTML — код:

Заметьте атрибуты action тега form — остались не тронуты! Пример с тегами FRAME:

ob_start(); output_add_rewrite_var('somevar', 'someval'); echo '  '; ob_end_flush();

Выдаст такой HTML — код:

Функцию output_add_rewrite_var() можно вызывать несколько раз с разными параметрами, в этом случае пары будут добавляться согласно формату кодирования данных: «application/x-www-form-urlencoded» разделяясь знаками амперсанда а в формы будут добавляться новые скрытые поля. Вот так будет выглядеть пример:

ob_start(); output_add_rewrite_var('somevar', 'someval'); output_add_rewrite_var('somevar1', 'someval1'); output_add_rewrite_var('somevar2', 'someval2'); echo ' 
'; echo 'LINK'; ob_end_flush();

Выдаст такой HTML — код:

А вот если в конце примера вызвать функцию output_reset_rewrite_vars() — то она отменит все изменения произведённые вызовами функций output_add_rewrite_var(. ) т.е. все ссылки вернуться к исходному состоянию.

Ну, вот надеюсь я доступно объяснил что такое буферизация вывода в PHP и с чем её едят.

Https://namars.com https://namars.com знаковых клипов группы Руки Вверх. namars.com

Этой ссылке Купить краску San Marko для стен с гарантией качества можно по этой ссылке. radugakraski.ru

ob_start

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

Содержимое этого внутреннего буфера может быть скопировано в строковую переменную, используя ob_get_contents() . Для вывода содержимого внутреннего буфера следует использовать ob_end_flush() . В качестве альтернативы можно использовать ob_end_clean() для очистки содержимого буфера.

Внимание

Некоторые веб-серверы (например, Apache) изменяют рабочую директорию скрипта при вызове callback-функции. Вы можете вернуть её назад, используя chdir(dirname($_SERVER[‘SCRIPT_FILENAME’])) в callback-функции.

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

Если буферизация вывода всё ещё активна, когда скрипт завершает работу, PHP автоматически выводит содержимое.

Список параметров

Можно задать необязательный параметр callback . Эта функция принимает строку в виде аргумента и должна также вернуть строку. Она вызывается при сбросе (отправке) или очистке (с помощью ob_flush() , ob_clean() или подобных функций) или если буфер вывода сбрасывается в браузер по окончанию запроса. При вызове функции callback , она получает содержимое буфера и, как ожидается, должна вернуть обновлённое содержимое для буфера вывода, которое будет отправлено браузеру. Если callback не является допустимой функцией, то эта функция вернёт false . Описание функции для этого параметра:

handler ( string $buffer , int $phase = ? ): string
buffer Содержимое буфера вывода. phase Битовая маска констант PHP_OUTPUT_HANDLER_* .

Если callback вернёт false , то оригинальная информация отправится в браузер без изменений.

Параметр callback может быть игнорирован передачей значения null .

ob_end_clean() , ob_end_flush() , ob_clean() , ob_flush() и ob_start() не могут вызываться из callback-функций, так как их поведение непредсказуемо. Если вы хотите удалить содержимое буфера, то верните «» (пустую строку) из callback-функции. Вы также не можете использовать функции буферизации вывода, такие как print_r($expression, true) или highlight_file($filename, true) из callback-функции.

Замечание:

Функция ob_gzhandler() была введена для облегчения отправки gz-кодированных данных браузерам, поддерживающим сжатые веб-страницы. ob_gzhandler() определяет тип кодировки содержимого, принимаемый браузером, и возвращает вывод соответствующим образом.

chunk_size

Если передан необязательный параметр chunk_size , то буфер буден сброшен после любого вывода, превышающего или равного по размеру chunk_size . Значение по умолчанию 0 означает, что функция вывода будет вызвана, когда буфер будет закрыт.

Параметр flags является битовой маской, которая управляет операциями, которые можно совершать над буфером вывода. По умолчанию она позволяет буферу вывода быть очищенным, сброшенным и удалённым, что равносильно значению PHP_OUTPUT_HANDLER_CLEANABLE | PHP_OUTPUT_HANDLER_FLUSHABLE | PHP_OUTPUT_HANDLER_REMOVABLE или PHP_OUTPUT_HANDLER_STDFLAGS как сокращение этой комбинации.

Каждый флаг управляет доступом к набору функций, как описано ниже:

Константа Функции
PHP_OUTPUT_HANDLER_CLEANABLE ob_clean() , ob_end_clean() и ob_get_clean() .
PHP_OUTPUT_HANDLER_FLUSHABLE ob_end_flush() , ob_flush() и ob_get_flush() .
PHP_OUTPUT_HANDLER_REMOVABLE ob_end_clean() , ob_end_flush() и ob_get_flush() .

Возвращаемые значения

Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.

Примеры

Пример #1 Пример callback-функции, определённой пользователем

function callback ( $buffer )
// заменить все яблоки апельсинами
return ( str_replace ( «яблоки» , «апельсины» , $buffer ));
>

Результат выполнения данного примера:

  

Это всё равно что сравнить апельсины и апельсины.

Пример #2 Создание нестираемого буфера вывода

ob_start ( null , 0 , PHP_OUTPUT_HANDLER_STDFLAGS ^ PHP_OUTPUT_HANDLER_REMOVABLE );

Смотрите также

  • ob_get_contents() — Возвращает содержимое буфера вывода
  • ob_end_clean() — Очистить (стереть) буфер вывода и отключить буферизацию вывода
  • ob_end_flush() — Сбросить (отправить) буфер вывод и отключить буферизацию вывода
  • ob_implicit_flush() — Включение/выключение неявного сброса
  • ob_gzhandler() — callback-функция, используемая для gzip-сжатия буфера вывода при вызове ob_start
  • ob_iconv_handler() — Преобразует символы из текущей кодировки в кодировку выходного буфера
  • mb_output_handler() — Callback-функция, преобразующая кодировку символов в выходном буфере
  • ob_tidyhandler() — Функция обратного вызова ob_start для восстановление буфера

Что делает php код

Эти ф-ции используются, например, для того, чтобы отрисовать шаблон, и HTML-код поместить в переменную.

21 авг 2015 в 17:28

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

Это сохранение в кеш.

PHP функция ob_start перехватывает весь последующий вывод в буфер и позволяет обработать его в конце работы скрипта. Простыми словами мы получаем весь контент сайта в переменной $content .

Для примера фрагмент:

ob_start(); include($file); $content = ob_get_clean(); 

Такую конструкцию применяют для рендеринга страниц, когда нужно в одну переменную записать динамически сгенерированную html страницу.

ob_start

Эта функция включит буферизацию вывода. Пока буферизация вывода активна, выходные данные из сценария не отправляются (кроме headers), вместо этого выходные данные сохраняются во внутреннем буфере).

Содержимое этого внутреннего буфера можно скопировать в строковую переменную с помощью ob_get_contents() . Для вывода того, что хранится во внутреннем буфере, используйте ob_end_flush() . Альтернативно, ob_end_clean() автоматически отбрасывает содержимое буфера.

Warning

Некоторые веб-серверы ((e.g. Apache) меняют рабочий каталог сценария при вызове функции обратного вызова. Вы можете изменить его обратно, например, chdir(dirname($_SERVER[‘SCRIPT_FILENAME’])) в функции обратного вызова.

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

Если буферизация вывода все еще активна после завершения сценария, PHP выводит содержимое автоматически.

Parameters

Можно указать дополнительную функцию callback . Эта функция принимает строку в качестве параметра и должна возвращать строку. Функция будет вызываться, когда выходной буфер сбрасывается (отправляется) или очищается (с помощью ob_flush() , ob_clean() или аналогичной функции) или когда выходной буфер сбрасывается в браузер в конце запроса. Когда вызывается callback , он получает содержимое выходного буфера в качестве параметра и, как ожидается, вернет в результате новый выходной буфер, который будет отправлен в браузер. Если callback не является вызываемой функцией, эта функция вернет false . Это подпись обратного вызова:

handler(string $buffer, int $phase = ?): string

buffer Содержимое выходного буфера. phase Битовая маска PHP_OUTPUT_HANDLER_* constants .

Если callback возвращает исходный ввод false , он отправляется в браузер.

Параметр callback можно обойти, передав значение null .

ob_end_clean() , ob_end_flush() , ob_clean() , ob_flush() и ob_start() нельзя вызывать из функции обратного вызова. Если вы вызываете их из функции обратного вызова, поведение не определено. Если вы хотите удалить содержимое буфера, верните «» (строку null) из функции обратного вызова. Вы даже не можете вызывать функции, используя функции буферизации вывода, такие как print_r($expression, true) или highlight_file($filename, true) , из функции обратного вызова.

Note:

Функция ob_gzhandler() предназначена для облегчения отправки данных в кодировке gz в веб-браузеры, поддерживающие сжатые веб-страницы. ob_gzhandler() определяет, какой тип кодировки содержимого принимает браузер, и соответствующим образом возвращает свои выходные данные.

chunk_size

Если передан необязательный параметр chunk_size , буфер будет сброшен после любого выходного вызова, в результате которого длина буфера станет равной или превысит chunk_size . Значение по умолчанию 0 означает, что функция вывода будет вызываться только тогда, когда выходной буфер закрыт.

Параметр flags — это битовая маска, управляющая операциями, которые можно выполнять с выходным буфером. По умолчанию разрешена очистка, очистка и удаление выходных буферов, что можно установить явно через PHP_OUTPUT_HANDLER_CLEANABLE | PHP_OUTPUT_HANDLER_FLUSHABLE | PHP_OUTPUT_HANDLER_REMOVABLE или PHP_OUTPUT_HANDLER_STDFLAGS как сокращение.

Каждый флаг контролирует доступ к набору функций, как описано ниже:

Constant Functions
PHP_OUTPUT_HANDLER_CLEANABLE ob_clean() , ob_end_clean() и ob_get_clean() .
PHP_OUTPUT_HANDLER_FLUSHABLE ob_end_flush() , ob_flush() и ob_get_flush() .
PHP_OUTPUT_HANDLER_REMOVABLE ob_end_clean() , ob_end_flush() и ob_get_flush() .

Return Values

Возвращает true в случае успеха или false в случае неудачи.

Examples

Пример #1 Пример пользовательской функции обратного вызова

 function callback($buffer) < // replace all the apples with oranges return (str_replace("apples", "oranges", $buffer)); > ob_start("callback"); ?> html> body> p>It's like comparing apples to oranges. p> body> html>  ob_end_flush(); ?>

В приведенном выше примере выводится:

html> body> p>It's like comparing oranges to oranges. p> body> html> 

Пример №2 Создание нестираемого выходного буфера

 ob_start(null, 0, PHP_OUTPUT_HANDLER_STDFLAGS ^ PHP_OUTPUT_HANDLER_REMOVABLE); ?>

See Also

  • ob_get_contents() — Возврат содержимого выходного буфера
  • ob_end_clean() — Очистка (стирание) выходного буфера и отключение выходной буферизации
  • ob_end_flush() — Flush (отправить) выходной буфер и отключить выходную буферизацию
  • ob_implicit_flush() — Поворот неявной промывки on/off
  • ob_gzhandler() — функция обратного вызова ob_start для выходного буфера gzip
  • ob_iconv_handler() — Преобразование кодировки символов в качестве обработчика выходного буфера
  • mb_output_handler() — функция обратного вызова преобразует кодировку символов в выходном буфере.
  • ob_tidyhandler() — функция обратного вызова ob_start для восстановления буфера.

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *

https://alkogolizm.vyvod-iz-zapoya-v-stacionare-samara11.ru/