output-buffering пример - Какая польза от ob_start()в php?




буферизация вывода (9)

В принятом ответе здесь описывается, что делает 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() для output buffering чтобы заголовки были буферизованы и не отправлены в браузер? Имею ли я смысл? Если нет, то почему мы должны использовать ob_start() ?


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


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

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

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


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

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


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

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

Я использую это, чтобы я мог вырваться из 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();
echo("Hello there!"); //would normally get printed to the screen/output to browser
$output = ob_get_contents();
ob_end_clean();

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


Я проклинал эту ошибку, но может быть полезно напомнить вам, чтобы избежать ввода пользователя.

Например, если вы считаете, что это умный, сокращенный код:

// Echo whatever the hell this is
<?=$_POST['something']?>

... Подумайте еще раз! Лучшее решение:

// If this is set, echo a filtered version
<?=isset($_POST['something']) ? html($_POST['something']) : ''?>

(Я использую пользовательскую функцию html() для запуска символов, ваш пробег может отличаться)





php output-buffering