PHP
Buffer de salida
Buscar..
Parámetros
Función | Detalles |
---|---|
ob_start () | Inicia el búfer de salida, cualquier salida colocada después de esto se capturará y no se mostrará |
ob_get_contents () | Devuelve todo el contenido capturado por ob_start() |
ob_end_clean () | Vacía el búfer de salida y lo desactiva para el nivel de anidamiento actual |
ob_get_clean () | Activa tanto ob_get_contents() como ob_end_clean() |
ob_get_level () | Devuelve el nivel de anidamiento actual del búfer de salida. |
ob_flush () | Descargue el búfer de contenido y envíelo al navegador sin finalizar el búfer |
ob_implicit_flush () | Habilita el vaciado implícito después de cada llamada de salida. |
ob_end_flush () | Vacíe el búfer de contenido y envíelo al navegador, también finalizando el búfer |
Uso básico obteniendo contenido entre buffers y clearing
El búfer de salida le permite almacenar cualquier contenido textual (Texto, HTML
) en una variable y enviarlo al navegador como una pieza al final de su script. Por defecto, php
envía su contenido como 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>"
Cualquier contenido ob_start()
entre ob_start()
y ob_get_clean()
será capturado y colocado en la variable $content
.
Al llamar a ob_get_clean()
ob_get_contents()
tanto ob_get_contents()
como ob_end_clean()
.
Buffers de salida anidados
Puede anidar buffers de salida y obtener el nivel para que proporcionen contenido diferente utilizando la función 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--;
}
Salidas:
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
Capturando el buffer de salida para reutilizarlo más tarde.
En este ejemplo, tenemos una matriz que contiene algunos datos.
$items_li_html
búfer de salida en $items_li_html
y lo usamos dos veces en la página.
<?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>
Guarde el código anterior en un archivo output_buffer.php
y ejecútelo a través de php output_buffer.php
.
Debería ver los 2 elementos de lista que creamos anteriormente con los mismos elementos de lista que generamos en PHP usando el búfer de salida:
<!-- 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>
Ejecutando buffer de salida antes de cualquier contenido.
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>
En este ejemplo, asumimos que $users
son una matriz multidimensional, y lo hacemos en bucle para encontrar a todos los usuarios con un nivel de acceso de 7.
Si no hay resultados, redirigimos a una página de error.
Estamos utilizando el búfer de salida aquí porque estamos activando un redireccionamiento de header()
basado en el resultado del bucle
Uso del búfer de salida para almacenar contenidos en un archivo, útil para informes, facturas, etc.
<?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);
Este ejemplo toma el documento completo y lo escribe en un archivo, no lo imprime en el navegador, pero lo hace usando echo $html;
Procesando el búfer a través de una devolución de llamada
Puede aplicar cualquier tipo de procesamiento adicional a la salida pasando un llamable 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();
*/
Salida:
<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>
Transmitir salida al cliente
/**
* 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 típico y razones para usar ob_start
ob_start
es especialmente útil cuando tienes redirecciones en tu página. Por ejemplo, el siguiente código no funcionará:
Hello!
<?php
header("Location: somepage.php");
?>
El error que se dará es algo como: headers already sent by <xxx> on line <xxx>
.
Para solucionar este problema, debe escribir algo como esto al comienzo de su página:
<?php
ob_start();
?>
Y algo como esto al final de tu página:
<?php
ob_end_flush();
?>
Esto almacena todo el contenido generado en un búfer de salida y lo muestra de una sola vez. Por lo tanto, si tiene llamadas de redirección en su página, éstas se activarán antes de que se envíe cualquier dato, eliminando la posibilidad de que se produzcan errores en los headers already sent
.