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

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

9 ответов


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


Я использую это, чтобы я мог вырваться из 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>';
?>

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

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

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

зачем....

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

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

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

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

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

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


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

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


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

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

это для дальнейшего уточнения ответа 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.';

вы можете захватить вывод, который генерируется здесь, и добавить его в два совершенно разных места в вашем макете.


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

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


такие вещи не упоминаются в существующих ответов : Настройки размера буфера заголовок http и гнездование.

настройки размера буфера для 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 будет отправлять большие куски данных, например, 4KB (wihout ob_start call, 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