Какое использование ob_start() в php?

Используется ли ob_start() для output buffering, чтобы заголовки были буферизованы и не отправлены в браузер? Имею ли я смысл? Если нет, то почему мы должны использовать ob_start()?

Ответ 1

Подумайте о 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(), который либо прекращает экономить вещи, либо отбрасывает все, что было сохранено, либо останавливает сохранение и выводит все сразу, соответственно.

Ответ 2

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

<?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>';
?>

Ответ 3

В принятом ответе здесь описывается, что делает ob_start() - а не почему он используется (о котором был задан вопрос).

Как указано в другом месте ob_start(), создается буфер, в который записывается вывод.

Но никто не упомянул, что можно стекировать несколько буферов в PHP. См. ob_get_level().

Что касается того, почему....

  • Отправка HTML в браузер в больших кусках дает преимущество в производительности благодаря уменьшенным сетевым ресурсам.

  • Передача данных из PHP в больших кусках дает преимущество производительности и емкости за счет сокращения количества требуемых контекстных переключателей.

  • Передача больших фрагментов данных в mod_gzip/mod_deflate дает преимущество в производительности, так как сжатие может быть более эффективным.

  • Буферизация вывода означает, что вы еще можете манипулировать заголовками HTTP позже в коде

  • явно очистка буфера после вывода [head].... [/head] может позволить браузеру начать маршалинг других ресурсов для страницы до завершения потока HTML. p >

  • Захват вывода в буфере означает, что он может перенаправляться на другие функции, такие как электронная почта, или скопировать в файл в виде кэшированного представления содержимого

Ответ 4

У вас есть это в обратном направлении. ob_start не буферизирует заголовки, он буферизирует содержимое. Использование ob_start позволяет сохранить содержимое в серверном буфере, пока вы не будете готовы его отображать.

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

Ответ 5

Я предпочитаю:

ob_start();
echo("Hello there!");
$output = ob_get_clean(); //Get current buffer contents and delete current output buffer

Ответ 6

это для дальнейшего уточнения ответа JD Isaaks...

Проблема, с которой вы сталкиваетесь часто, заключается в том, что вы используете php для вывода html из разных источников php, и эти источники часто по какой-либо причине выводят по-разному.

Иногда у вас есть буквальный html-контент, который вы хотите напрямую выводить в браузер; в других случаях вывод динамически создается (на стороне сервера).

Динамический контент всегда (?) будет строкой. Теперь вам нужно объединить этот стробированный динамический html с любым литералом, прямым отображением html... в одну значимую структуру html node.

Это обычно заставляет разработчика обертывать все содержимое прямого отображения в строку (как обсуждал 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>

Ответ 7

Эта функция предназначена не только для заголовков. Вы можете сделать много интересного с этим. Пример. Вы можете разделить свою страницу на разделы и использовать ее так:

$someTemplate->selectSection('header');
echo 'This is the header.';

$someTemplate->selectSection('content');
echo 'This is some content.';

Вы можете записать полученный здесь результат и добавить его в два совершенно разных места в вашем макете.

Ответ 8

Нет, вы ошибаетесь, но направление подходит;)

Буферизация вывода буферизует вывод script. Thats (короче) когда-либо после echo или print. Дело в заголовках заключается в том, что их можно отправить только, если они еще не отправлены. Но HTTP говорит, что заголовки являются первыми в передаче. Поэтому, если вы выходите что-то в первый раз (в запросе), отправляются заголовки, и вы не можете устанавливать другие заголовки.

Ответ 9

В существующих ответах не упоминаются следующие вещи: Конфигурация размера буфера 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 КБ (вызов w_out 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