Ob start php что это

от admin

ob_start

This function will turn output buffering on. While output buffering is active no output is sent from the script (other than headers), instead the output is stored in an internal buffer.

The contents of this internal buffer may be copied into a string variable using ob_get_contents . To output what is stored in the internal buffer, use ob_end_flush . Alternatively, ob_end_clean will silently discard the buffer contents.

Some web servers (e.g. Apache) change the working directory of a script when calling the callback function. You can change it back by e.g. chdir(dirname($_SERVER['SCRIPT_FILENAME'])) in the callback function.

Output buffers are stackable, that is, you may call ob_start while another ob_start is active. Just make sure that you call ob_end_flush the appropriate number of times. If multiple output callback functions are active, output is being filtered sequentially through each of them in nesting order.

Parameters

An optional output_callback function may be specified. This function takes a string as a parameter and should return a string. The function will be called when the output buffer is flushed (sent) or cleaned (with ob_flush , ob_clean or similar function) or when the output buffer is flushed to the browser at the end of the request. When output_callback is called, it will receive the contents of the output buffer as its parameter and is expected to return a new output buffer as a result, which will be sent to the browser. If the output_callback is not a callable function, this function will return FALSE . This is the callback signature:

If output_callback returns FALSE original input is sent to the browser.

The output_callback parameter may be bypassed by passing a NULL value.

ob_end_clean , ob_end_flush , ob_clean , ob_flush and ob_start may not be called from a callback function. If you call them from callback function, the behavior is undefined. If you would like to delete the contents of a buffer, return "" (a null string) from callback function. You can't even call functions using the output buffering functions like print_r($expression, true) or highlight_file($filename, true) from a callback function.

Note:

ob_gzhandler function exists to facilitate sending gz-encoded data to web browsers that support compressed web pages. ob_gzhandler determines what type of content encoding the browser will accept and will return its output accordingly.

If the optional parameter chunk_size is passed, the buffer will be flushed after any output call which causes the buffer's length to equal or exceed chunk_size . The default value 0 means that the output function will only be called when the output buffer is closed.

Prior to PHP 5.4.0, the value 1 was a special case value that set the chunk size to 4096 bytes.

The flags parameter is a bitmask that controls the operations that can be performed on the output buffer. The default is to allow output buffers to be cleaned, flushed and removed, which can be set explicitly via PHP_OUTPUT_HANDLER_CLEANABLE | PHP_OUTPUT_HANDLER_FLUSHABLE | PHP_OUTPUT_HANDLER_REMOVABLE , or PHP_OUTPUT_HANDLER_STDFLAGS as shorthand.

Each flag controls access to a set of functions, as described below:

Constant Functions
PHP_OUTPUT_HANDLER_CLEANABLE ob_clean , ob_end_clean , and ob_get_clean .
PHP_OUTPUT_HANDLER_FLUSHABLE ob_end_flush , ob_flush , and ob_get_flush .
PHP_OUTPUT_HANDLER_REMOVABLE ob_end_clean , ob_end_flush , and ob_get_flush .

Return Values

Returns TRUE on success or FALSE on failure.

Changelog

Version Description
7.0.0 In case ob_start is used inside an output buffer callback, this function will no longer issue an E_ERROR but instead an E_RECOVERABLE_ERROR , allowing custom error handlers to catch such errors.
5.4.0 The third parameter of ob_start changed from a boolean parameter called erase (which, if set to FALSE , would prevent the output buffer from being deleted until the script finished executing) to an integer parameter called flags . Unfortunately, this results in an API compatibility break for code written prior to PHP 5.4.0 that uses the third parameter. See the flags example for an example of how to handle this with code that needs to be compatible with both.
5.4.0 A chunk size of 1 now results in chunks of 1 byte being sent to the output buffer.
4.3.2 This function was changed to return FALSE in case the passed output_callback can not be executed.

Examples

Example #1 User defined callback function example

function callback ( $buffer )
<
// replace all the apples with oranges
return ( str_replace ( «apples» , «oranges» , $buffer ));
>

PHP для начинающих. Буфер вывода // PHP

Продолжаю публиковать статьи из серии «PHP для начинающих», в этот раз речь пойдёт о буфере вывода.

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

Для начала, даю установку — буферов вывода в PHP несколько, плюс ещё модули web-сервера могут выполнять буферизацию, да ещё и браузеры могут играться с выводом и не сразу отображать полученный результат (надо бы тут освежить память, а то за упоминание Netscape могут освежевать).

Вот теперь буду рассказывать о буферизации в PHP.

Пользовательский буфер вывода

Работа с буфером вывода начинается с функции ob_start() — у данной функции есть три опциональных параметра, но о них я расскажу чуть позже, а пока запоминаем — для включения буфера вывода используем функцию ob_start() :

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

Практически все нужные нам функции имеют префикс «ob_», как не трудно догадаться это сокращение от «output buffer»

Функцию ob_get_contents() можно вызывать множество раз, на практике с таким не сталкивался:

Если вы стартанули буфер вывода, но по какой-то причине не закрыли его, то PHP это сделает за вас и в конце работы скрипта выполнит «сброс» буфера вывода в браузер пользователя

Если внутри блока ob_start – ob_end вы отправляете заголовок, то он не попадает в буфер, а сразу будет отправлен в браузер:

В результате выполнения данного кода в http-пакете появятся следующие заголовки:

Естественно, данный код больше ничего не выводит, будет пустая страница.

Данное правило по отправке заголовков верно как для непосредственного вызова функции header() , так и для неявного при вызове session_start() :

Перед вами небольшой life-hack – в PHP вы можете использовать скобочки <> для выделения некой логики в блоки, при этом никакой функциональной нагрузки они не несут, а вот читаемость кода – повышают

Чуть-чуть прояснили ситуацию — теперь в копилке наших знаний есть информация о том, как включить буфер, как получить из него данные, и как выключить. Что ещё интересное можно с ним вытворять? Да с ним практически ничего толком и не сделать — его можно отправить (сбросить) в браузер (ключевое слово flush), очистить (clean), отключить (end). Ну и скомбинировать это всё до кучи тоже можно:

  • ob_clean() — читаем название функции как «очищаем буфер вывода»
  • ob_flush() — «отправляем буфер вывода»
  • ob_end_clean() — «буфер вывода отключаем и очищаем»
  • ob_end_flush() — «буфер вывода отключаем и отправляем в браузер»
  • ob_get_clean() — «получаем буфер вывода, очищаем и отключаем» — тут небольшой отступление от правила, эта функция должна именоваться как ob_get_end_clean() , но решили упростить, и выкинули end
  • ob_get_flush() — «отправляем буфер вывода, очищаем и отключаем», ob_get_ end _flush()

Что можно из перечисленного делать с буфером вывода, определяется третьим опциональным параметром $flags при вызове функции ob_start() , используется крайне редко

Для простого запоминания вот вам наглядная табличка по данному семейству функций:

вернёт очистит отправит отключит
ob_get_contents X
ob_clean X
ob_flush X
ob_end_clean X X
ob_end_flush X X
ob_get_clean X X X
ob_get_flush X X X

Задание
Дополните приведенный ниже код вызовом одной функции, чтобы он корректно вывел «hello world»:

Обработчик буфера

Пора вернуться к функции ob_start() и её первому параметру — $output_callback — обработчик буфера вывода. В качестве обработчика буфера должна быть указана callback-функция, которая принимает содержимое буфера как входной параметр и должна вернуть строку после обработки:

В данном примере функция обработчик вернёт строку «Length of string ‘hello world’ is 11».

Важный момент — с этими функциями нужно быть поосторожней, обработали строки и ладненько, но не пытайтесь вывести либо сохранить данные, не пытайтесь стартовать другой буфер вывода внутри функции, и да есть функции которые создают буфер вывода внутри себя, вот print_r() и highlight_file() тому пример

Из стандартных же обработчиков можете повстречать ob_gzhandler(), но лучше сжатие страничек оставлять на плечах web-сервера, и не вешать это на PHP.

Ещё момент, второй параметр $phase callback-функции может включать в себя флаги из семейства PHP_OUTPUT_HANDLER_* , но вам эта информация никогда не понадобится, я даже пример не смог придумать, зачем оно надо.

We need to go deeper©

Inception

У буфера вывода есть килер-фича – внутри буфера можно стартовать ещё один буфер, а внутри нового ещё и так далее (пока памяти хватает):

В данном примере функция ob_flush() и производные от неё, будут «выбрасывать» содержимое буфера на более высокий уровень.

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

Если вы не знаете точно на какой «глубине» находитесь – то воспользуйтесь функцией ob_get_level(), а чтобы «проснуться» вам пригодится следующий код:

Задание
Внесите изменения в код с вложенными вызовами ob_start() таким образом, чтобы цифры выводились в обратном порядке, для этого надо переставить три строчки кода.

Буфер «по умолчанию»

Если захотите создать обёртку над всем кодом, то для этого можно воспользоваться решением «из коробки» — буфер вывода «по умолчанию», за активацию оного отвечает директива output_buffering, её можно выставить как в On , так и указать размер буфера который нам потребуется (при достижении лимита, буфер будет отправлен в браузер пользователю). Данная директива должна быть проставлена либо в php.ini, либо в .htaccess (для апача), попытка выставить данное значение с использование ini_set() ни к чему не приведёт, т.к. PHP уже стартанул, и буфер вывода уже сконфигурирован согласно настроек:

Если при включенном буфере проверить уровень вложенности и вызвать функцию ob_get_level() , то получим 1:

Т.е. если включить данный буфер, то можно будет избежать ошибок вида «headers already sent»? Да, пока буфера хватит, но никогда так не делайте, ведь понадеявшись на данный метод, вы фактически заложите бомбу замедленного действия, и неизвестно когда она «рванёт» и посыпит ошибками:

Запомните, для CLI приложений директива output_buffering всегда 0, т.е. данный буфер отключен

Зачем это всё?

Хороший вопрос — зачем нужна работа с буфером вывода? Приведу несколько основных сценариев использования:

  1. Сжатие передаваемых данных — с использованием уже упомянутой ob_gzhandler()
  2. Отложенный вывод, чтобы избежать ошибки «headers already sent» (о данной ошибке подробно рассказано в статье Сессия)
  3. Работа с чужим кодом, который пытается самостоятельно что-то выводить
  4. Работа с HTML файлами: когда вам надо подключать текстовый файл (обычно речь о HTML), для дальнейшей работы с его содержимым

Сценарий обработки ошибок в подключаемых файлах — стартуете буфер, подключаете файлы, если что-то пошло не так, то содержимое буфера можно скинуть, и вместо неинформативного сообщения об ошибке, выводите не менее информативное сообщение, что сервер приболел, и не может больше ничего.
Пример работы с критическими ошибками вы можете найти в статье Обработка ошибок, и там тоже упоминается буфер вывода, ох видать всё это ж-ж-ж неспроста

Системный буфер вывода

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

Вот так всё просто и кратко, ну а теперь о нюансах управления системным буфером вывода…

Royal flush

10 секунд вашего внимания…

А теперь из академического интереса давайте рассмотрим реализацию данного «экшена» – там совсем чуть-чуть кода, и небольшая горстка полезных знаний по PHP:

Сразу бросается в глаза вызов функции flush() — вызвав данную функцию вы даёте указание PHP «сбросить» системный буфер, т.е. отправить всё что там есть в браузер пользователю (но учтите, если у вас стартован пользовательский буфер, то для начала надо будет «сбросить» его, и уже потом вызвать flush() ). Т.е. происходящее можно описать как:

Ещё одна особенность, о которой нужно помнить — директива implicit_flush, отвечает за то, чтобы после каждого вывода автоматически вызывался flush() , поэтому следующая комбинация сработает аналогично предыдущему примеру:

Данную директиву можно изменять «на лету», для этого достаточно вызвать функцию ob_implicit_flush() (удивительное рядом, данную функцию стоило всё же назвать implicit_flush() , т.к. к пользовательскому буферу вывода она имеет опосредственное отношение — после вызова ob_flush() будет вызван flush() ):

Данные примеры работают только при выключенном output_buffering , иначе вам нужно будет его принудительно выключить и очистить в самом скрипте. Если же вы работаете в CLI, то знайте implicit_flush всегда включён, а output_buffering выключен, следовательно весь вывод будет без промедления попадать в консоль

Задание

Для выполнения данного задания вам потребуется освежить знания по подключению файлов

Для закрепления изученного материала, вам нужно реализовать простейший шаблонизатор, который оживит следующий код:

Рекомендованная литература

  • Хардкорно про буфер вывода в статье PHP output buffer in deep (перевод Буфер вывода в PHP)
  • Ссылка на официальное руководство по настройка php.ini
  • Статья Streaming and Output Buffering

В заключение

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

PHP ob_start() Function

The ob_start() function creates an output buffer. A callback function can be passed in to do processing on the contents of the buffer before it gets flushed from the buffer. Flags can be used to permit or restrict what the buffer is able to do.

Syntax

Parameter Values

Parameter Description
callback Optional. A callback used to process the contents of the buffer before it gets flushed.

A bitmask which determines what operations the buffer is permitted to do. It may contain the following flags:

PHP_OUTPUT_HANDLER_CLEANABLE — Calls to ob_clean(), ob_end_clean() and ob_get_clean() are permitted.

PHP_OUTPUT_HANDLER_FLUSHABLE — Calls to ob_flush(), ob_end_flush() and ob_get_flush() are permitted.

PHP_OUTPUT_HANDLER_REMOVABLE — Calls to ob_end_clean(), ob_end_flush() and ob_get_flush() are permitted.

Использование ob_start при поддержке проектов на php

Сегодня я бы хотел познакомить начинающих вебмастеров с разнообразными изящными способами использования буферизации вывода в php. Опытные вебмастера для себя здесь врят ли найдут что-то полезное. Хотя — кто знает?

Как вы все знаете, буферизацией вывода в php управляет набор функций, начинающихся на «ob_». Самая главная из них — ob_start. При запуске она собирает последующий вывод, то есть всевозможные print(), echo и прочее, что потом отдастся посетителю в форме html-странички. И если перед тем, как выводить, мы запустили буферизацию, то с этой, почти готовой уже, страничкой, можно будет напоследок что-нибудь сотворить.

Например, мы хотим отфильтровать все ссылки на посторонние сайты.

На нашем, древнем как топор австралопитека, форуме, роится великое множество спамеров, заманивающих посетителя в места, заполненные развратом, однорукими бандитами и политической агитацией. Можно было бы использовать js со слежением, но мы хотим вместо этого изменить все эти ссылки так:

Способ может быть и не самый эффективный, но действенный. Мы написали redirect.php с фильтром и черным листом, и теперь нам надо преобразовывать все ссылки на тысячах страниц форума. С помощью ob_start и парочки регулярных выражений мы сделаем это всего в несколько строк:

Теперь, там, где мы добавили в контент появится то, что мы хотели получить. Одно из применений — вставка виджета js на страницу сайта. Например, яндекс-карты. Обычно это не составляет никакого труда, но иногда криво написанный редактор страниц сайта экранирует кавычки и фигурные скобки, ломая виджет. Как видим, эта проблема легко решается.

Набор инструментов php для работы с буффером вывода богат, и не ограничивается одним лишь ob_start. Вышеописанные приемы в некоторых случаях излишне ресурсоемки и громоздки, поскольку оперируют со всей страницей. Мы можем обработать только ее часть, создав в шаблоне оболочку вокруг генерации чего-то, в дебри чего нам не хочется лезть, но что обязательно нужно поправить:

Должно быть, вы уже заметили все эти обороты: «не хочется лезть», «древний, как стул тиранозавра», «криво написанный редактор»… В идеальном мире оболочки вокруг буфера вывода не нужны. Все что можно сделать с помощью ob_start, теоретически можно было бы сделать и без него. Этот прием иной раз вносит путанницу в код проекта, многие видят его смысл лишь в том, что бы отдать вывод в ob_gzhandler для сжатия, и считают его применение в иных случаях опасным. Но часто без управления выводом просто не обойтись.

Читать:
Как сделать галерею для товара

Похожие статьи