Jaki jest pożytek z OB start () w php?

Czy ob_start() jest używany do output buffering, aby nagłówki były buforowane i nie wysyłane do przeglądarki? Czy to ma sens? Jeśli nie, to dlaczego powinniśmy używać ob_start()?

Author: jfmercer, 2010-12-09

9 answers

Pomyśl o ob_start() jako o powiedzeniu: "Zacznij pamiętać wszystko, co normalnie zostanie wypisane, ale nie rób jeszcze nic z tym."

Na przykład:

ob_start();
echo("Hello there!"); //would normally get printed to the screen/output to browser
$output = ob_get_contents();
ob_end_clean();

Są dwie inne funkcje, z którymi zwykle się go sparowuje: ob_get_contents(), która w zasadzie daje to, co zostało "zapisane" do bufora, ponieważ zostało włączone za pomocą ob_start(), a następnie ob_end_clean() lub ob_flush(), która albo przestaje zapisywać rzeczy i odrzuca to, co zostało zapisane, albo przestaje zapisywać i wypisuje wszystko na raz, odpowiednio.

 511
Author: Riley Dutton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-24 11:29:29

Używam tego, aby móc wyrwać się z PHP z dużą ilością HTML, ale nie renderować go. To ratuje mnie od przechowywania go jako ciąg znaków, który wyłącza kodowanie kolorów IDE.

<?php
ob_start();
?>
<div>
    <span>text</span>
    <a href="#">link</a>
</div>
<?php
$content = ob_get_clean();
?>

Zamiast:

<?php
$content = '<div>
    <span>text</span>
    <a href="#">link</a>
</div>';
?>
 169
Author: JD Isaacks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-02-12 15:48:20

Przyjęta odpowiedź opisuje to, co ob_start() robi - nie dlaczego jest używana (co było zadawane pytanie).

Jak podano w innym miejscu ob_start() tworzy bufor, do którego dane wyjściowe są zapisywane.

Ale nikt nie wspomniał, że możliwe jest stos Wielu buforów w PHP. Zobacz ob_get_level().

Co do przyczyny....
  1. Wysyłanie HTML do przeglądarki w większych kawałkach daje korzyści z wydajności zmniejszonej sieci nad głową.

  2. Przekazywanie danych z PHP w większych kawałkach daje korzyści z wydajności i pojemności poprzez zmniejszenie liczby wymaganych przełączników kontekstowych

  3. Przekazywanie większych porcji danych do mod_gzip / mod_deflate daje korzyści wydajnościowe, ponieważ kompresja może być bardziej wydajna.

  4. Buforowanie wyjścia oznacza, że można nadal manipulować nagłówkami HTTP później w kodzie

  5. Explicite flushing the bufor po wystąpieniu [head]....[/head] może pozwolić przeglądarce na rozpoczęcie tworzenia innych zasobów dla strony przed zakończeniem strumienia HTML.

  6. Przechwytywanie danych wyjściowych w buforze oznacza, że można je przekierować do innych funkcji, takich jak poczta e-mail, lub skopiować do pliku jako buforowaną reprezentację zawartości

 91
Author: symcbean,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-04 19:42:37

Masz to na odwrót. ob_start nie buforuje nagłówków, tylko buforuje zawartość. Użycie ob_start pozwala zachować zawartość w buforze po stronie serwera, dopóki nie będziesz gotowy do wyświetlenia jej.

Jest to powszechnie używane do tego, aby strony mogły wysyłać nagłówki "po", że już "wysłały" jakąś zawartość (tj. decydując się na przekierowanie w połowie renderowania strony).

 29
Author: Craige,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-09 18:57:43

Wolę:

ob_start();
echo("Hello there!");
$output = ob_get_clean(); //Get current buffer contents and delete current output buffer
 13
Author: hawx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-13 12:02:57

To jest do dalszego wyjaśnienia JD Isaaks odpowiedź ...

Problem, na który często wpadasz, polega na tym, że używasz php do generowania kodu html z wielu różnych źródeł php, a te źródła są często, niezależnie od powodu, wysyłane na różne sposoby.

Czasami masz dosłowną zawartość html, którą chcesz bezpośrednio wypuścić do przeglądarki; innym razem wyjście jest dynamicznie tworzone (po stronie serwera).

Dynamiczna zawartość jest zawsze(?) będzie sznurkiem. Teraz musisz połączyć ten stringified dynamiczny html z dowolnym dosłownym, bezpośrednim do wyświetlania html ... w jedną znaczącą strukturę węzła html.

To zwykle zmusza programistę do zawijania całej zawartości bezpośrednio do wyświetlania w ciąg znaków (jak omawiał JD Isaak), aby mogła być poprawnie dostarczona/wstawiona w połączeniu z dynamicznym html ... nawet jeśli nie chcesz tego zapakować.

Ale używając metod ob_# # można uniknąć tego bałaganu. Dosłowne zawartość jest natomiast wyprowadzana do bufora. Następnie w jednym prostym kroku cała zawartość bufora (cały twój dosłowny html) jest konkatenowana w dynamicznym łańcuchu html.

(Mój przykład pokazuje, że literalny html jest wyprowadzany do bufora, który jest następnie dodawany do łańcucha html ... spójrz również na przykład JD Isaaks aby zobaczyć 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>
 9
Author: dsdsdsdsd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-03-01 15:40:23

Ta funkcja nie jest tylko dla nagłówków. Możesz z tym zrobić wiele ciekawych rzeczy. Przykład: możesz podzielić stronę na sekcje i używać jej w następujący sposób:

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

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

Możesz uchwycić wygenerowane tutaj Dane wyjściowe i dodać je w dwóch zupełnie różnych miejscach w swoim układzie.

 4
Author: jwueller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-09 18:57:16

Następujące rzeczy nie są wymienione w istniejących odpowiedziach : Konfiguracja rozmiaru bufora Nagłówek HTTP i gniazdowania.

Konfiguracja rozmiaru bufora dla 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.

Powyższy kod poprawia wydajność serwera, ponieważ PHP wyśle większe ilości danych, na przykład 4KB(wywołanie ob_start, php wyśle każde echo do przeglądarki).

Jeśli zaczniesz buforować bez rozmiaru fragmentu (np. prostym ob_start ()), wtedy strona zostanie wysłana raz na końcu scenariusz.

Buforowanie wyjścia nie wpływa na nagłówki HTTP, są one przetwarzane w inny sposób. Jednak ze względu na buforowanie można wysłać nagłówki nawet po wysłaniu wyjścia, ponieważ nadal znajduje się ono w buforze.

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

Ładnie wyjaśnione tutaj: https://phpfashion.com/everything-about-output-buffering-in-php

 4
Author: sudip,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-23 07:33:32

Nie, mylisz się, ale kierunek pasuje;)

Bufor wyjściowy buforuje wyjście skryptu. To (w skrócie) wszystko po echo LUB print. Rzecz z nagłówkami jest taka, że mogą zostać wysłane tylko wtedy, gdy nie są już wysłane. Ale HTTP mówi, że nagłówki są pierwszym transmisji. Więc jeśli wypisujesz coś po raz pierwszy (w żądaniu) nagłówki są wysyłane i nie możesz ustawić żadnych innych nagłówków.

 0
Author: KingCrunch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-09 18:57:49