ob_get_contents - ¿Cuál es el uso de ob_start() en PHP?
php ob_start echo (9)
¿ ob_start()
usa ob_start()
para output buffering
para que los encabezados se almacenen en búfer y no se envíen al navegador? ¿Estoy teniendo sentido aquí? Si no es así, ¿por qué deberíamos usar ob_start()
?
Esta función no es sólo para los encabezados. Puedes hacer muchas cosas interesantes con esto. Ejemplo: Podrías dividir tu página en secciones y usarla así:
$someTemplate->selectSection(''header'');
echo ''This is the header.'';
$someTemplate->selectSection(''content'');
echo ''This is some content.'';
Puede capturar la salida que se genera aquí y agregarla en dos lugares totalmente diferentes en su diseño.
Esto es para aclarar aún más la respuesta de JD Isaaks ...
El problema con el que se encuentra a menudo es que está utilizando php para generar html desde muchas fuentes de php diferentes, y esas fuentes a menudo, por el motivo que sea, lo hacen a través de diferentes formas.
A veces, tiene contenido HTML literal que desea enviar directamente al navegador; otras veces, la salida se crea de forma dinámica (lado del servidor).
El contenido dinámico siempre es (?) Va a ser una cadena. Ahora tiene que combinar este html dinámico con cualquier html literal, directo a mostrar ... en una estructura de nodo html significativa.
Por lo general, esto obliga al desarrollador a envolver todo el contenido de visualización directa en una cadena (como JD Isaak estaba discutiendo) para que pueda ser entregado / insertado correctamente junto con el html dinámico ... aunque en realidad no quiero envuelto.
Pero al usar los métodos ob _ ## puede evitar ese desorden de ajuste de cadena. El contenido literal es, en cambio, salida al búfer. Luego, en un solo paso, todo el contenido del búfer (todo su html literal), se concatena en su cadena dinámica-html.
(Mi ejemplo muestra la salida de html literal al búfer, que luego se agrega a una cadena html ... vea también el ejemplo de JD Isaaks para ver el ajuste de cadena de 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>
La respuesta aceptada aquí describe lo que hace ob_start()
, no por qué se usa (que fue la pregunta).
Como se indica en otra parte, ob_start()
crea un búfer en el que se escribe la salida.
Pero nadie ha mencionado que es posible apilar múltiples buffers dentro de PHP. Ver ob_get_level ().
En cuanto al por qué ...
El envío de HTML al navegador en partes más grandes brinda un beneficio de rendimiento al reducir la sobrecarga de la red.
Pasar los datos fuera de PHP en partes más grandes brinda un beneficio de rendimiento y capacidad al reducir la cantidad de cambios de contexto requeridos
Pasar trozos más grandes de datos a mod_gzip / mod_deflate proporciona un beneficio de rendimiento en el sentido de que la compresión puede ser más eficiente.
el almacenamiento en búfer de la salida significa que aún puede manipular los encabezados HTTP más adelante en el código
el vaciado explícito del búfer después de emitir la [cabecera] .... [/ cabecera] puede permitir que el navegador comience a calcular recursos de la página antes de que se complete la secuencia HTML.
Capturar la salida en un búfer significa que puede redirigirse a otras funciones, como el correo electrónico, o copiarse en un archivo como una representación en caché del contenido.
Las siguientes cosas no se mencionan en las respuestas existentes: Configuración de tamaño de búfer Encabezado HTTP y anidamiento.
Configuración de tamaño de búfer para 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.
El código anterior mejora el rendimiento del servidor, ya que PHP enviará grandes porciones de datos, por ejemplo, 4 KB (sin una llamada ob_start, php enviará cada eco al navegador).
Si inicia el almacenamiento en búfer sin el tamaño del fragmento (es decir, un simple ob_start ()), la página se enviará una vez al final del script.
El búfer de salida no afecta a los encabezados HTTP, se procesan de manera diferente. Sin embargo, debido al almacenamiento en búfer puede enviar los encabezados incluso después de que se envió la salida, porque todavía está en el búfer.
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
Muy bien explicado aquí: https://phpfashion.com/everything-about-output-buffering-in-php
Lo tienes al revés. ob_start no almacena los encabezados, almacena el contenido. El uso de ob_start
permite mantener el contenido en un búfer del lado del servidor hasta que esté listo para mostrarlo.
Esto se usa comúnmente para que las páginas puedan enviar encabezados "después de" que ya hayan "enviado" algo de contenido (es decir, que decidan redirigir a mitad de la representación de una página).
No, estás equivocado, pero la dirección encaja;)
El búfer de salida amortigua la salida de un script. Eso es (en resumen) todo después de echo
o print
. Lo que pasa con los encabezados es que solo se pueden enviar, si aún no se han enviado. Pero HTTP dice, que los encabezados son los primeros de la transmisión. Por lo tanto, si imprime algo por primera vez (en una solicitud), los encabezados se envían y no puede establecer ningún otro encabezado.
Piense en ob_start()
como diciendo "Comience a recordar todo lo que normalmente se emitiría, pero no haga nada con eso todavía".
Por ejemplo:
ob_start();
echo("Hello there!"); //would normally get printed to the screen/output to browser
$output = ob_get_contents();
ob_end_clean();
Hay otras dos funciones con las que normalmente se ob_get_contents()
: ob_get_contents()
, que básicamente le da todo lo que se ha "guardado" en el búfer desde que se activó con ob_start()
, y luego ob_end_clean()
u ob_flush()
, que deja de guardar cosas y descarta cualquier cosa que se haya guardado, o deja de guardar y envía todo a la vez, respectivamente.
Utilizo esto para poder salir de PHP con un montón de HTML pero no mostrarlo. Me ahorra almacenarlo como una cadena que desactiva la codificación de colores.
<?php
ob_start();
?>
<div>
<span>text</span>
<a href="#">link</a>
</div>
<?php
$content = ob_get_clean();
?>
En lugar de:
<?php
$content = ''<div>
<span>text</span>
<a href="#">link</a>
</div>'';
?>
Yo prefiero:
ob_start();
echo("Hello there!");
$output = ob_get_clean(); //Get current buffer contents and delete current output buffer