PHP
Buffering di uscita
Ricerca…
Parametri
Funzione | Dettagli |
---|---|
ob_start () | Avvia il buffer di output, qualsiasi output posizionato dopo questo verrà catturato e non visualizzato |
ob_get_contents () | Restituisce tutto il contenuto catturato da ob_start() |
ob_end_clean () | Svuota il buffer di output e lo spegne per il livello di annidamento corrente |
ob_get_clean () | ob_get_contents() entrambi ob_get_contents() e ob_end_clean() |
ob_get_level () | Restituisce il livello di annidamento corrente del buffer di output |
ob_flush () | Scaricare il buffer del contenuto e inviarlo al browser senza terminare il buffer |
ob_implicit_flush () | Abilita lo svuotamento implicito dopo ogni chiamata in uscita. |
ob_end_flush () | Scarica il buffer del contenuto e invialo al browser, terminando anche il buffer |
Utilizzo di base per ottenere il contenuto tra i buffer e la cancellazione
Il buffering dell'output consente di memorizzare qualsiasi contenuto testuale (testo, HTML
) in una variabile e di inviarlo al browser come un pezzo alla fine del copione. Per impostazione predefinita, php
invia il tuo contenuto mentre lo interpreta.
<?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>"
Qualsiasi contenuto emesso tra ob_start()
e ob_get_clean()
verrà catturato e inserito nella variabile $content
.
La chiamata a ob_get_clean()
attiva sia ob_get_contents()
che ob_end_clean()
.
Buffer di output annidati
È possibile nidificare i buffer di output e recuperare il livello per fornire contenuti diversi utilizzando la funzione 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--;
}
Uscite:
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
Catturare il buffer di output da riutilizzare in seguito
In questo esempio, abbiamo una matrice contenente alcuni dati.
$items_li_html
buffer di output in $items_li_html
e lo usiamo due volte nella pagina.
<?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>
Salva il codice sopra in un file output_buffer.php
ed output_buffer.php
tramite php output_buffer.php
.
Dovresti vedere i 2 elementi della lista che abbiamo creato sopra con gli stessi elementi della lista che abbiamo generato in PHP usando il buffer di output:
<!-- 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>
Esecuzione del buffer di output prima di qualsiasi contenuto
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>
In questo esempio, supponiamo che gli $users
siano una matrice multidimensionale, e lo attraversiamo per trovare tutti gli utenti con un livello di accesso 7.
Se non ci sono risultati, reindirizziamo a una pagina di errore.
Stiamo utilizzando il buffer di output qui perché stiamo attivando un reindirizzamento header()
base al risultato del ciclo
Utilizzo del buffer di output per archiviare i contenuti in un file, utile per report, fatture, ecc
<?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);
Questo esempio prende il documento completo e lo scrive in un file, non emette il documento nel browser, ma lo fa usando echo $html;
Elaborazione del buffer tramite un callback
Puoi applicare qualsiasi tipo di elaborazione aggiuntiva all'output passando un callable a 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();
*/
Produzione:
<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>
Trasmetti l'output al client
/**
* 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();
}
Uso tipico e motivi per l'utilizzo di ob_start
ob_start
è particolarmente utile quando hai i reindirizzamenti sulla tua pagina. Ad esempio, il seguente codice non funzionerà:
Hello!
<?php
header("Location: somepage.php");
?>
L'errore che verrà dato è qualcosa di simile: headers already sent by <xxx> on line <xxx>
.
Per risolvere questo problema, dovresti scrivere qualcosa di simile all'inizio della pagina:
<?php
ob_start();
?>
E qualcosa di simile alla fine della tua pagina:
<?php
ob_end_flush();
?>
Questo memorizza tutto il contenuto generato in un buffer di output e lo visualizza in un colpo solo. Quindi, se hai delle chiamate di reindirizzamento sulla tua pagina, queste si innescano prima che vengano inviati tutti i dati, rimuovendo la possibilità che un headers already sent
errore.