PHP: manipulando o buffer de saída
Algumas vezes em PHP é interessante que ao invés de condicionar a saída ou não de algum texto como estamos acostumados, manipular o texto depois de montado.
Isso pode ser conseguido em alguns casos trocando todas as chamadas a print e echo por concatenações em uma variável global, para então no fim do script efetuar a impressão de seu conteúdo.
Antes…
print cabecalho();
print conteudo();
print rodape();
Depois…
$html = cabecalho();
$html .= conteudo();
$html .= rodape();
$html = efetua_algum_processamento($html);
echo $html;
Mas essa abordagem além de demandar muitas substituições em alguns casos, não atende quando há partes do programa (como bibliotecas de terceiros) em que você não tem controle do código, ou onde alterações podem acarretar em efeitos colaterais indesejados.
Por padrão, a cada chamada a print ou echo o texto é enviado e portanto não pode ser mais mudado. No entanto, se o output buffering for ativado, os textos impressos vão para um buffer ao invés de serem impressos imediatamente. Então, bem como usando variáveis, os valores do buffer podem ser lidos e modificados de acordo com a necessidade.
Existem várias funções para manipualação desse buffer, sendo as principais:
- ob_start
Ativa o buffer de saída. - ob_flush
Efetua o envio do conteúdo do buffer. O buffer é esvaziado após o envio. - ob_clean
Descarta o conteúdo do buffer sem enviar. - ob_get_contents
Retorna o conteúdo do buffer. - ob_get_flush
Retorna o conteúdo do buffer, efetua o envio e esvazia. - ob_end_clean
Desabilita o buffer de saída e descarta seu conteúdo. - ob_end_flush
Envia o conteúdo do buffer de saída e então o desabilita.
Exemplo de uso
// Ativa o output buffering
ob_start();
// Execução normal da página, geração do HTML etc.
// joga em uma variável o conteúdo do buffer
$html = ob_get_contents();
// esvazia o buffer descartando seu conteúdo
ob_clean();
// troca as ocorrências de "laranja" por "maçã"
$html = str_replace("laranja", "maçã", $html);
// desativa o output buffering, enviando o conteúdo do buffer
ob_end_flush();
Output buffering e os headers
Que atire a primeira pedra quem nunca se deparou com esse erro:
Warning: Cannot send session cookie – headers already sent by (output started at /var/www/index.php:XX) in /var/www/index.php on line XX
Isso ocorre sempre que se tenta enviar um header (ou alguma outra ação que o faça, como iniciar uma sessão ou enviar um cookie) depois de imprimir conteúdo.
Se uma chamada a ob_start() for feita no início do script e então out chamada a ob_end_flush() no fim, não será mais necessário se preocupar em colocar os headers sempre antes do conteúdo. Afinal, todo o conteúdo será acumulado para envio apenas no fim da execução.
Processamento do buffer por callback
Se o seu buffer de saída tem sempre o mesmo processamento, você pode passar uma função de callback para a função ob_start(). Isso seria equivalente ao exemplo anterior, onde o buffer é recuperado, processado e então impresso, mas é mais simples.
Tudo o que você tem a fazer é criar uma função que receba o conteúdo original e retorne o conteúdo a ser impresso efetivamente. Informando seu nome como parâmetro de ob_start, ao chamar ob_end_flush() sua função será chamada automaticamente com o conteúdo do buffer como argumento.
Exemplo:
function callback($buffer){
return str_replace("red", "blue", $buffer);
}
ob_start("callback");
gera_conteudo(); // geração do conteúdo da página
ob_end_flush();
Conclusão
Esse é o básico que se pode fazer com o output buffering. Na maioria das vezes que ele for necessário será em um desses casos. Mas vale a pena experimentar e olhar com detalhes a documentação das funções de output buffering, pois essa etapa adicional de pós-processamento pode dar margem a soluções e idéias interessantes, como plugins e mods que alteram o comportamento padrão de aplicativos (como os plugins do WordPress).
Deixe um comentário