É ob_start()
usado para output buffering
que os cabeçalhos sejam armazenados em buffer e não enviados para o navegador? Estou fazendo sentido aqui? Se não, então por que devemos usar ob_start()
?
É ob_start()
usado para output buffering
que os cabeçalhos sejam armazenados em buffer e não enviados para o navegador? Estou fazendo sentido aqui? Se não, então por que devemos usar ob_start()
?
Respostas:
Pense ob_start()
no seguinte: "Comece a se lembrar de tudo o que normalmente seria produzido, mas ainda não faça nada com isso".
Por exemplo:
ob_start();
echo("Hello there!"); //would normally get printed to the screen/output to browser
$output = ob_get_contents();
ob_end_clean();
Em geral, existem duas outras funções com as quais você o emparelha ob_get_contents()
:, que basicamente fornece o que foi "salvo" no buffer desde que foi ligado ob_start()
e, em seguida , ob_end_clean()
ou ob_flush()
, que pára de salvar as coisas e descarta o que foi salvo ou pára de salvar e produz tudo de uma vez, respectivamente.
ob_start();
Isso está correto? O que acontece se não estiver ativado?
ob_end_clean
ele funciona como um encanto! Obrigado @Riley Dutton
Eu uso isso para que eu possa sair do PHP com muito HTML, mas não renderizá-lo. Isso me impede de armazená-lo como uma string que desativa o código de cores IDE.
<?php
ob_start();
?>
<div>
<span>text</span>
<a href="#">link</a>
</div>
<?php
$content = ob_get_clean();
?>
Ao invés de:
<?php
$content = '<div>
<span>text</span>
<a href="#">link</a>
</div>';
?>
ob_get_clean()
, não ob_end_clean()
A resposta aceita aqui descreve o que ob_start()
faz - não o motivo pelo qual é usada (qual foi a pergunta).
Como declarado em outro lugar, ob_start()
cria um buffer no qual a saída é gravada.
Mas ninguém mencionou que é possível empilhar vários buffers no PHP. Veja ob_get_level ().
Quanto ao porquê ....
O envio de HTML para o navegador em partes maiores oferece um benefício de desempenho devido a uma sobrecarga de rede reduzida.
A transmissão dos dados do PHP em partes maiores fornece um benefício de desempenho e capacidade, reduzindo o número de alternâncias de contexto necessárias
A transmissão de grandes pedaços de dados para mod_gzip / mod_deflate oferece um benefício de desempenho, pois a compactação pode ser mais eficiente.
armazenar em buffer a saída significa que você ainda pode manipular os cabeçalhos HTTP posteriormente no código
A liberação explícita do buffer após a saída do [head] .... [/ head] pode permitir que o navegador comece a organizar outros recursos da página antes da conclusão do fluxo HTML.
Capturar a saída em um buffer significa que ele pode ser redirecionado para outras funções, como email, ou copiado para um arquivo como uma representação em cache do conteúdo.
Você tem isso ao contrário. ob_start não armazena em buffer os cabeçalhos, armazena em buffer o conteúdo. Usar ob_start
permite manter o conteúdo em um buffer do servidor até que você esteja pronto para exibi-lo.
Isso é comumente usado para que as páginas já possam enviar cabeçalhos 'depois que' eles 'enviaram' algum conteúdo (por exemplo, decidir redirecionar a meio da renderização de uma página).
isso é para esclarecer melhor a resposta de JD Isaaks ...
O problema com que você se depara com freqüência é que você está usando o php para gerar html de muitas fontes diferentes de php, e essas fontes são, por qualquer motivo, geradas de maneiras diferentes.
Às vezes, você possui conteúdo literal em html que deseja gerar diretamente no navegador; outras vezes, a saída está sendo criada dinamicamente (do lado do servidor).
O conteúdo dinâmico será sempre (?) Uma string. Agora você tem que combinar esse html dinâmico estrito com qualquer html literal, direto para exibição ... em uma estrutura de nó html significativa.
Isso geralmente força o desenvolvedor a agrupar todo o conteúdo direto para exibição em uma string (como JD Isaak estava discutindo) para que ele possa ser entregue / inserido corretamente em conjunto com o html dinâmico ... mesmo que você não realmente quero embrulhado.
Mas, usando os métodos ob _ ##, você pode evitar essa confusão de quebra de cadeia. Em vez disso, o conteúdo literal é enviado para o buffer. Em uma etapa fácil, todo o conteúdo do buffer (todo o seu html literal) é concatenado na sua seqüência de html dinâmico.
(Meu exemplo mostra a saída literal de html no buffer, que é adicionado a uma string html ... veja também o exemplo de JD Isaaks para ver a string-wrap-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>
Esta função não é apenas para cabeçalhos. Você pode fazer muitas coisas interessantes com isso. Exemplo: você pode dividir sua página em seções e usá-la assim:
$someTemplate->selectSection('header');
echo 'This is the header.';
$someTemplate->selectSection('content');
echo 'This is some content.';
Você pode capturar a saída gerada aqui e adicioná-la em dois lugares totalmente diferentes no seu layout.
O seguinte não é mencionado nas respostas existentes: Configuração do tamanho do buffer HTTP Header and Nesting.
Configuração do tamanho do buffer 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.
O código acima melhora o desempenho do servidor, pois o PHP envia grandes quantidades de dados, por exemplo, 4KB (sem chamada ob_start, o php envia cada eco ao navegador).
Se você começar a armazenar em buffer sem o tamanho do pedaço (por exemplo, um simples ob_start ()), a página será enviada uma vez no final do script.
O buffer de saída não afeta os cabeçalhos HTTP, eles são processados de maneira diferente. No entanto, devido ao buffer, você pode enviar os cabeçalhos mesmo após o envio, porque ele ainda está no buffer.
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
Bem explicado aqui: https://phpfashion.com/everything-about-output-buffering-in-php
Não, você está errado, mas a direção se encaixa;)
O buffer de saída armazena em buffer a saída de um script. Isso é (em suma) tudo depois echo
ou print
. A coisa com os cabeçalhos é que eles só podem ser enviados, se ainda não tiverem sido enviados. Mas o HTTP diz que os cabeçalhos são os primeiros da transmissão. Portanto, se você produzir algo pela primeira vez (em uma solicitação), os cabeçalhos serão enviados e você não poderá definir outros cabeçalhos.
ob_get_contents()
comob_get_clean()
e removerob_end_clean()
uma vez queob_get_clean()
executa essencialmente ambas as funções. Referência: php.net/manual/pt/function.ob-get-clean.php (PHP 4> = 4.3.0, PHP 5)