PHP
Buforowanie wyjściowe
Szukaj…
Parametry
Funkcjonować | Detale |
---|---|
ob_start () | Uruchamia bufor wyjściowy, wszelkie umieszczone po nim dane wyjściowe zostaną przechwycone i nie zostaną wyświetlone |
ob_get_contents () | Zwraca całą treść przechwyconą przez ob_start() |
ob_end_clean () | Opróżnia bufor wyjściowy i wyłącza go dla bieżącego poziomu zagnieżdżenia |
ob_get_clean () | ob_get_contents() zarówno ob_get_contents() i ob_end_clean() |
ob_get_level () | Zwraca bieżący poziom zagnieżdżenia bufora wyjściowego |
ob_flush () | Opróżnij bufor zawartości i wyślij go do przeglądarki bez kończenia bufora |
ob_implicit_flush () | Umożliwia niejawne płukanie po każdym wywołaniu wyjściowym. |
ob_end_flush () | Opróżnij bufor zawartości i wyślij go do przeglądarki, również kończąc bufor |
Podstawowe użycie pobierania zawartości między buforami i czyszczenia
Buforowanie danych wyjściowych pozwala przechowywać dowolną treść tekstową (tekst, HTML
) w zmiennej i wysyłać do przeglądarki jako jeden element na końcu skryptu. Domyślnie php
wysyła twoją treść tak, jak ją interpretuje.
<?php
// Turn on output buffering
ob_start();
// Print some output to the buffer (via php)
print 'Hello ';
// You can also `step out` of PHP
?>
<em>World</em>
<?php
// Return the buffer AND clear it
$content = ob_get_clean();
// Return our buffer and then clear it
# $content = ob_get_contents();
# $did_clear_buffer = ob_end_clean();
print($content);
#> "Hello <em>World</em>"
Wszelkie treści wyprowadzane między ob_start()
a ob_get_clean()
zostaną przechwycone i umieszczone w zmiennej $content
.
Wywołanie ob_get_clean()
uruchamia zarówno ob_get_contents()
i ob_end_clean()
.
Zagnieżdżone bufory wyjściowe
Możesz zagnieździć bufory wyjściowe i pobrać ich poziom, aby zapewnić inną zawartość za pomocą funkcji ob_get_level()
.
<?php
$i = 1;
$output = null;
while( $i <= 5 ) {
// Each loop, creates a new output buffering `level`
ob_start();
print "Current nest level: ". ob_get_level() . "\n";
$i++;
}
// We're at level 5 now
print 'Ended up at level: ' . ob_get_level() . PHP_EOL;
// Get clean will `pop` the contents of the top most level (5)
$output .= ob_get_clean();
print $output;
print 'Popped level 5, so we now start from 4' . PHP_EOL;
// We're now at level 4 (we pop'ed off 5 above)
// For each level we went up, come back down and get the buffer
while( $i > 2 ) {
print "Current nest level: " . ob_get_level() . "\n";
echo ob_get_clean();
$i--;
}
Wyjścia:
Current nest level: 1
Current nest level: 2
Current nest level: 3
Current nest level: 4
Current nest level: 5
Ended up at level: 5
Popped level 5, so we now start from 4
Current nest level: 4
Current nest level: 3
Current nest level: 2
Current nest level: 1
Przechwytywanie bufora wyjściowego do ponownego wykorzystania później
W tym przykładzie mamy tablicę zawierającą niektóre dane.
Przechwytujemy bufor wyjściowy w $items_li_html
i używamy go dwa razy na stronie.
<?php
// Start capturing the output
ob_start();
$items = ['Home', 'Blog', 'FAQ', 'Contact'];
foreach($items as $item):
// Note we're about to step "out of PHP land"
?>
<li><?php echo $item ?></li>
<?php
// Back in PHP land
endforeach;
// $items_lists contains all the HTML captured by the output buffer
$items_li_html = ob_get_clean();
?>
<!-- Menu 1: We can now re-use that (multiple times if required) in our HTML. -->
<ul class="header-nav">
<?php echo $items_li_html ?>
</ul>
<!-- Menu 2 -->
<ul class="footer-nav">
<?php echo $items_li_html ?>
</ul>
Zapisz powyższy kod w pliku output_buffer.php
i uruchom go przez php output_buffer.php
.
Powinieneś zobaczyć 2 elementy listy, które utworzyliśmy powyżej, z tymi samymi elementami listy, które wygenerowaliśmy w PHP przy użyciu bufora wyjściowego:
<!-- Menu 1: We can now re-use that (multiple times if required) in our HTML. -->
<ul class="header-nav">
<li>Home</li>
<li>Blog</li>
<li>FAQ</li>
<li>Contact</li>
</ul>
<!-- Menu 2 -->
<ul class="footer-nav">
<li>Home</li>
<li>Blog</li>
<li>FAQ</li>
<li>Contact</li>
</ul>
Uruchamianie bufora wyjściowego przed jakąkolwiek zawartością
ob_start();
$user_count = 0;
foreach( $users as $user ) {
if( $user['access'] != 7 ) { continue; }
?>
<li class="users user-<?php echo $user['id']; ?>">
<a href="<?php echo $user['link']; ?>">
<?php echo $user['name'] ?>
</a>
</li>
<?php
$user_count++;
}
$users_html = ob_get_clean();
if( !$user_count ) {
header('Location: /404.php');
exit();
}
?>
<html>
<head>
<title>Level 7 user results (<?php echo $user_count; ?>)</title>
</head>
<body>
<h2>We have a total of <?php echo $user_count; ?> users with access level 7</h2>
<ul class="user-list">
<?php echo $users_html; ?>
</ul>
</body>
</html>
W tym przykładzie zakładamy, że $users
jest tablicą wielowymiarową i przeglądamy ją, aby znaleźć wszystkich użytkowników z poziomem dostępu 7.
Jeśli nie ma wyników, przekierowujemy na stronę błędu.
Używamy tutaj bufora wyjściowego, ponieważ uruchamiamy przekierowanie header()
na podstawie wyniku pętli
Używanie bufora wyjściowego do przechowywania zawartości w pliku, przydatne do raportów, faktur itp
<?php
ob_start();
?>
<html>
<head>
<title>Example invoice</title>
</head>
<body>
<h1>Invoice #0000</h1>
<h2>Cost: £15,000</h2>
...
</body>
</html>
<?php
$html = ob_get_clean();
$handle = fopen('invoices/example-invoice.html', 'w');
fwrite($handle, $html);
fclose($handle);
Ten przykład pobiera cały dokument i zapisuje go do pliku, nie wysyła dokumentu do przeglądarki, ale robi to za pomocą echo $html;
Przetwarzanie bufora za pośrednictwem wywołania zwrotnego
Możesz zastosować dowolny rodzaj dodatkowego przetwarzania na wyjściu, przekazując ob_start()
do ob_start()
.
<?php
function clearAllWhiteSpace($buffer) {
return str_replace(array("\n", "\t", ' '), '', $buffer);
}
ob_start('clearAllWhiteSpace');
?>
<h1>Lorem Ipsum</h1>
<p><strong>Pellentesque habitant morbi tristique</strong> senectus et netus et malesuada fames ac turpis egestas. <a href="#">Donec non enim</a> in turpis pulvinar facilisis.</p>
<h2>Header Level 2</h2>
<ol>
<li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
<li>Aliquam tincidunt mauris eu risus.</li>
</ol>
<?php
/* Output will be flushed and processed when script ends or call
ob_end_flush();
*/
Wynik:
<h1>LoremIpsum</h1><p><strong>Pellentesquehabitantmorbitristique</strong>senectusetnetusetmalesuadafamesacturpisegestas.<ahref="#">Donecnonenim</a>inturpispulvinarfacilisis.</p><h2>HeaderLevel2</h2><ol><li>Loremipsumdolorsitamet,consectetueradipiscingelit.</li><li>Aliquamtinciduntmauriseurisus.</li></ol>
Przesyłaj dane wyjściowe do klienta
/**
* Enables output buffer streaming. Calling this function
* immediately flushes the buffer to the client, and any
* subsequent output will be sent directly to the client.
*/
function _stream() {
ob_implicit_flush(true);
ob_end_flush();
}
Typowe zastosowanie i powody używania ob_start
ob_start
jest szczególnie przydatny, gdy masz przekierowania na swojej stronie. Na przykład następujący kod nie będzie działać:
Hello!
<?php
header("Location: somepage.php");
?>
Podany błąd jest podobny do: headers already sent by <xxx> on line <xxx>
.
Aby rozwiązać ten problem, na początku swojej strony napisałbyś coś takiego:
<?php
ob_start();
?>
I coś takiego na końcu twojej strony:
<?php
ob_end_flush();
?>
Przechowuje całą wygenerowaną zawartość w buforze wyjściowym i wyświetla ją za jednym razem. W związku z tym, jeśli na Twojej stronie są wywołania przekierowania, zostaną one uruchomione przed wysłaniem jakichkolwiek danych, co eliminuje możliwość wystąpienia błędu headers already sent
.