Является ли ob_start()
использовать для output buffering
так, чтобы заголовки в буфер и не передаются в браузер? Имею ли я здесь смысл? Если нет, то почему мы должны использовать ob_start()
?
Является ли ob_start()
использовать для output buffering
так, чтобы заголовки в буфер и не передаются в браузер? Имею ли я здесь смысл? Если нет, то почему мы должны использовать ob_start()
?
Ответы:
Думайте о том, ob_start()
как сказать: «Начни вспоминать все, что обычно выводится, но пока не делай с этим ничего».
Например:
ob_start();
echo("Hello there!"); //would normally get printed to the screen/output to browser
$output = ob_get_contents();
ob_end_clean();
Есть две другие функции, с которыми вы обычно связываете его:, ob_get_contents()
который в основном дает вам все, что было «сохранено» в буфере с момента его включения ob_start()
, и затем ob_end_clean()
или ob_flush()
, который либо прекращает сохранять вещи и сбрасывает то, что было сохранено, либо прекращает сохранение и выводит все сразу, соответственно.
ob_start();
Это правильно? Что произойдет, если он не включен?
ob_end_clean
ним работает как шарм! Спасибо @Riley Даттон
Я использую это, чтобы вырваться из PHP с большим количеством HTML, но не отображать его. Это спасает меня от сохранения в виде строки, которая отключает цветовое кодирование IDE.
<?php
ob_start();
?>
<div>
<span>text</span>
<a href="#">link</a>
</div>
<?php
$content = ob_get_clean();
?>
Вместо того:
<?php
$content = '<div>
<span>text</span>
<a href="#">link</a>
</div>';
?>
ob_get_clean()
, а не ob_end_clean()
Принятый ответ здесь описывает, что ob_start()
делает, а не почему он используется (который был задан вопрос).
Как указано в другом месте, ob_start()
создается буфер, в который записывается вывод.
Но никто не упомянул, что в PHP можно размещать несколько буферов. Смотрите ob_get_level ().
Что касается того, почему ....
Отправка HTML-кода в браузер большими порциями дает выигрыш в производительности благодаря уменьшению нагрузки на сеть.
Передача данных из PHP большими блоками дает выигрыш в производительности и емкости за счет уменьшения количества необходимых переключений контекста
Передача больших массивов данных в mod_gzip / mod_deflate дает выигрыш в производительности, поскольку сжатие может быть более эффективным.
буферизация вывода означает, что вы все еще можете манипулировать заголовками HTTP позже в коде
явное очищение буфера после вывода [head] .... [/ head] может позволить браузеру начать маршалинг других ресурсов для страницы до завершения потока HTML.
Захват вывода в буфер означает, что он может быть перенаправлен на другие функции, такие как электронная почта, или скопирован в файл в качестве кэшированного представления содержимого.
У тебя это задом наперед. ob_start не буферизует заголовки, он буферизует содержимое. Использование ob_start
позволяет вам хранить содержимое в буфере на стороне сервера, пока вы не будете готовы его отобразить.
Это обычно используется для того, чтобы страницы могли отправлять заголовки после того, как они «отправили» уже некоторый контент (то есть, решили перенаправить на полпути при рендеринге страницы).
это для дальнейшего уточнения JD Isaaks ответ ...
Проблема, с которой вы часто сталкиваетесь, заключается в том, что вы используете php для вывода html из разных источников php, и эти источники часто по какой-либо причине выводятся разными способами.
Иногда у вас есть буквальный HTML-контент, который вы хотите напрямую выводить в браузер; в других случаях вывод создается динамически (на стороне сервера).
Динамический контент всегда (?) Будет строкой. Теперь вам нужно объединить этот строковый динамический html с любым буквальным html, предназначенным для непосредственного отображения ... в одну значимую структуру html-узла.
Это обычно вынуждает разработчика заключать весь этот контент для отображения в строку (как обсуждал JD Isaak), чтобы его можно было правильно доставлять / вставлять в сочетании с динамическим html ... даже если вы на самом деле этого не делаете хочу обернуть.
Но, используя методы ob _ ##, вы можете избежать этой путаницы. Литеральное содержимое вместо этого выводится в буфер. Затем одним простым шагом все содержимое буфера (все ваши литералы html) объединяются в вашу строку dynamic-html.
(Мой пример показывает, что литеральный html выводится в буфер, который затем добавляется в html-строку ... посмотрите также на пример JD Isaaks, чтобы увидеть string-wrapping-of-html).
<?php // parent.php
//---------------------------------
$lvs_html = "" ;
$lvs_html .= "<div>html</div>" ;
$lvs_html .= gf_component_assembler__without_ob( ) ;
$lvs_html .= "<div>more html</div>" ;
$lvs_html .= "----<br/>" ;
$lvs_html .= "<div>html</div>" ;
$lvs_html .= gf_component_assembler__with_ob( ) ;
$lvs_html .= "<div>more html</div>" ;
echo $lvs_html ;
// 02 - component contents
// html
// 01 - component header
// 03 - component footer
// more html
// ----
// html
// 01 - component header
// 02 - component contents
// 03 - component footer
// more html
//---------------------------------
function gf_component_assembler__without_ob( )
{
$lvs_html = "<div>01 - component header</div>" ; // <table ><tr>" ;
include( "component_contents.php" ) ;
$lvs_html .= "<div>03 - component footer</div>" ; // </tr></table>" ;
return $lvs_html ;
} ;
//---------------------------------
function gf_component_assembler__with_ob( )
{
$lvs_html = "<div>01 - component header</div>" ; // <table ><tr>" ;
ob_start();
include( "component_contents.php" ) ;
$lvs_html .= ob_get_clean();
$lvs_html .= "<div>03 - component footer</div>" ; // </tr></table>" ;
return $lvs_html ;
} ;
//---------------------------------
?>
<!-- component_contents.php -->
<div>
02 - component contents
</div>
Эта функция не только для заголовков. Вы можете сделать много интересного с этим. Пример: вы можете разбить свою страницу на разделы и использовать ее следующим образом:
$someTemplate->selectSection('header');
echo 'This is the header.';
$someTemplate->selectSection('content');
echo 'This is some content.';
Вы можете захватить сгенерированный здесь вывод и добавить его в двух совершенно разных местах макета.
Следующие вещи не упомянуты в существующих ответах: Конфигурация размера буфера HTTP Header и Nesting.
Настройка размера буфера для ob_start:
ob_start(null, 4096); // Once the buffer size exceeds 4096 bytes, PHP automatically executes flush, ie. the buffer is emptied and sent out.
Приведенный выше код повышает производительность сервера, так как PHP будет отправлять большие куски данных, например, 4 КБ (без вызова ob_start, php отправляет каждое эхо-сообщение в браузер).
Если вы начнете буферизацию без размера чанка (т.е. простого ob_start ()), то страница будет отправлена один раз в конце скрипта.
Буферизация вывода не влияет на заголовки HTTP, они обрабатываются по-разному. Однако из-за буферизации вы можете отправлять заголовки даже после того, как выходные данные были отправлены, потому что они все еще находятся в буфере.
ob_start(); // turns on output buffering
$foo->bar(); // all output goes only to buffer
ob_clean(); // delete the contents of the buffer, but remains buffering active
$foo->render(); // output goes to buffer
ob_flush(); // send buffer output
$none = ob_get_contents(); // buffer content is now an empty string
ob_end_clean(); // turn off output buffering
Хорошо объяснено здесь: https://phpfashion.com/everything-about-output-buffering-in-php
Нет, вы не правы, но направление подходит;)
Буферизация вывода буферизует вывод скрипта. Вот (короче) все после echo
или print
. Проблема с заголовками в том, что они могут быть отправлены, только если они еще не отправлены. Но HTTP говорит, что заголовки - это самая первая передача. Поэтому, если вы выводите что-то впервые (в запросе), заголовки отправляются, и вы не можете устанавливать другие заголовки.
ob_get_contents()
сob_get_clean()
и удалить ,ob_end_clean()
так как поob_get_clean()
существу , выполняет обе функции. Ссылка: php.net/manual/en/function.ob-get-clean.php (PHP 4> = 4.3.0, PHP 5)