Entendendo pra que serve ob_start(), ob_end_flush(), ob_get_contents() e afins

Prefácio

Se você mexe com PHP há um certo tempo, com certeza já deve ter visto em algum lugar estas funções e talvez tenha se perguntando para que elas servem.

A primeira vista pode parecer algo extremamente complexo e avançado, mas a resposta é mais simples do que se imagina.

Conceito

Em primeiro lugar, você precisa saber o que significa esta sigla: OB. Deixando de lado o fato de que muita gente pensou besteira, OB significa Output Buffer, que nada mais é do que o Buffer de saída.

Buffer á uma região da memória onde os dados ficam armazenados temporariamente até que sejam despejados para a aplicação. Nesse caso, o buffer seria a saída pro navegador.

E qual a utilidade disso?
Você já deve ter se deparado com algum erro que dizia Headers already sent. Isso se dá porque já foi enviada alguma saída para o navegador. Cabeçalhos só podem ser enviados antes de qualquer saída html.

Um ob_start() irá pegar todos os dados de saída e guardar em buffer. Os dados só serão enviados ao navegador no momento em que você encerrar o buffer.

Existem três meios de encerrar o flush:

1. ob_end_flush(): Envia o conteúdo do buffer para a saída, esvazia-o e encerra o buffering;
2. ob_flush(): Envia o valor do buffer para o navegador e esvazia-o. Todas as entradas a seguir continuam indo para o buffer;
3. ob_end_clean(): Esvazia o buffer e encerra-o. Nenhuma saída é enviada.

Adicionalmente você pode utilizar a função ob_clean(), que apenas limpa o buffer.

Outra função que é muito importante é a ob_get_contents(), que irá retornar o conteúdo do buffer.

A seguir, veremos um exemplo simples de como guardar o retorno do phpinfo() dentro de um arquivo, utilizando o buffer para não enviar a saída para o navegador.

Mão na massa

Em primeiro lugar devemos iniciar o buffer. Depois iremos prosseguir como se fossemos executar o phpinfo() normalmente, porém a saída será guardada no buffer ao ivés de jogada na tela. Em seguida pegamos o resultado do buffer e gravamos em um arquivo HTML.

<?php

    // Inicializa o buffer e bloqueia qualquer saída para o navegador
    ob_start();

    // Executamos o phpinfo() normalmente
    phpinfo();

    // Neste momento nenhuma saída foi enviada ao navegador

    // Recebemos o valor do buffer na variável $resultado
    $resultado = ob_get_contents();

    // Já podemos encerrar o buffer e limpar tudo que há nele
    ob_end_clean();

    // Agora é só gravar um arquivo com os dados coletados
    $ok = file_put_contents('phpinfo.html', $resultado);

    // Envia uma mensagem para o usuário indicando se ocorreu tudo OK
    if ($ok) {
        print 'Arquivo gravado com sucesso.<br />';
        print '<a href="phpinfo.html">Clique aqui para visualizar</a>';
    } else {
        print 'Ocorreu um erro. Verifique o permissionamento.';
    }

?>

Conclusão

Trabalhar com buffer é ter milhões de possibilidades nas mãos. Você pode encontrar diversas utilidades para o seu uso. Eu gostaria muito que vocês comentasses sobre suas experiências utilizando estas técnicas.

Lembrando sempre: toda sugetão para novas colunas são sempre bem vindas!

Um abraço a todos e fiquem com Deus!
Rafael Jaques

Esta entrada foi publicada em Buffer, Comandos avançados e marcada com a tag , . Adicione o link permanente aos seus favoritos.

13 pessoas já comentaram! Tá esperando o quê?

  1.  
    faael disse:

    Legal, não conhecia essas funções.

    Bom saber que elas existem, e que podem ser úteis :D

    Valeu por explicar ;)

    Abraço.

    Utilizando Mozilla Firefox Mozilla Firefox 3.0.5 no Windows Windows Vista
  2.  
    SQUIK disse:

    Rafael, trabalhar com as funções de buffer não seria a mesa coisa que trabalhar com $_session????

    Alguns dia atrás tive um problema, pois para algumas paginas do meu site vinha um erro antes do start_session();, depois de pesquisar muito, descobri que a codificação do meu documento php não tinha o formato padrão, as funções decritas acima resolveriam o meu problema??

    Utilizando Mozilla Firefox Mozilla Firefox 3.0.5 no Windows Windows Vista
  3.  

    Cara, esse OB_start me deu uma baile tempos atrás. Desenvolvi um sistema que rodava perfeitamente localmente em qualquer navegador, e online rodav apenas no firefox, sendo que problema diagnosticado foi que o Internet Explorer(qualquer versão) não estava conseguindo resgatar os dados gravados na sessão, parecia q simplesmente a sessão morria. A solução foi bufferizar todo conteúdo logo após iniciar a sessão, e mandar um cabelho from hell pro IE manter o buffer em cache, segue o famigerado código de iníco das páginas do sistema:

    <?php

    header('P3P: CP="CAO PSA OUR"');

    ob_start();

    //Resto do sistema

    ?>

    Certas coisas somente a microsoft entende mesmo…

    Utilizando Mozilla Firefox Mozilla Firefox 3.0.6 no Windows Windows Vista
  4.  

    Faltou o principal, se algúem por aew pegar um problema do IE não consguir gravar nem ler na sessão, coloca akele código logo após iniciar a sessão que não tem erro, problema resolvido!

    Utilizando Mozilla Firefox Mozilla Firefox 3.0.6 no Windows Windows Vista
  5.  
    Humberto disse:

    Uma outra utilizadade destas funções é na criação de templates, onde vc teria um arquivo com o conteudo e algum padrão que seria substituido por um conteudo dinamico.

    Utilizando Mozilla Firefox Mozilla Firefox 3.0.6 no Windows Windows XP
  6.  
    Rafael Jaques disse:

    Squik..

    Na verdade uma coisa não tem a ver com a outra…

    A session vai trabalhar com as variáveis de sessão da tua aplicação..

    E estas funções trabalham com o buffer.. O buffer é apenas a saída pro navegador..

    É claro que, usando buffer, você pode neutralizar alguns bugs de sessão, quando você envia saidas indesejadas ao navegador..

    Mas não sei se vai resolver o seu problema..

    Abraço!

    Utilizando Mozilla Firefox Mozilla Firefox 3.0.6 no Mac OS X Mac OS X 10
  7.  
    Vinícius disse:

    Gostei do Post. Muito informativo. Continuem por favor, mal posso esperar pelo próximo.

    Utilizando Mozilla Firefox Mozilla Firefox 3.5.3 no Windows Windows XP
  8.  
    Denis Lins disse:

    Te amo cara! kkk

    Me ajudou muito isso, achei meio sem quere este post mas foi de grande ajuda, valeu! :D

    Utilizando Mozilla Firefox Mozilla Firefox 3.6.3 no Windows Windows 7
  9.  
    Allan disse:

    Não conhecia este site a gostei realmente muito!

    Sigam em frente que, pela qualidade, o site vai bombar!

    Parabéns!!!

    Utilizando Internet Explorer Internet Explorer 8.0 no Windows Windows 7
  10.  
    Juliana disse:

    gostei, estava procurando algo assim para enviar uma imagem gerada no php para um email… agora vamos ver se vai dar certo! obrigada!

    Utilizando Mozilla Firefox Mozilla Firefox 3.6.10 no Windows Windows 7
  11.  
    adrian disse:

    Muito bom!!

    Ainda não conhecia essas funções e realmente são muitas as possibilidades de uso.

    Estou tentando fazer um pequeno sistema de chat e acho que essa é uma função ideal.

    Utilizando Google Chrome Google Chrome 11.0.696.68 no Windows Windows 7
  12.  
    augustowebd disse:

    belo artigo, parabéns.

    aproveitando, uma coisa que pode ser feito utilizando o conjunto de funções apresentadas é um esquema de cache de view. simples e poderoso.

    []

    Utilizando Mozilla Firefox Mozilla Firefox 3.6.17 no Ubuntu Linux Ubuntu Linux
  13.  
    Roseane disse:

    Oi Rafael. Eu to com um probleminha acontecendo no meu script e talvez você possa me ajudar. Estou usando a biblioteca FPDF para gerar relatórios online. Só que quando há muita informação no relatório (imprime um retorno de sql grande), da o seguinte erro "Fatal error: Allowed memory size of…". O FPDF armazena os dados em buffer antes de imprimir. Só que nos meus testes descobri que o buffer não está sendo limpo a cada requisição. Meu php está configurado com 16M de memória. Para testar, fui aumentando gradativamente para 17M, 18M, 19M, 20M… em todos esses casos o erro persistiu. Então aumentei para 30M e consegui imprimir o relatório sem erros. Mas como o relatório está em desenvolvimento ainda, fui imprimindo várias vezes (gerando várias requisições) até que o erro apareceu de novo, dizendo que 30M já não eram mais suficientes. Tentei usar a função ob_clean() mas apresenta o seguinte notice "Notice: ob_clean() [ref.outcontrol]: failed to delete buffer. No buffer to delete. ". Eu poderia colocar um ini_set() com um valor bem grande para a memória, mas como esse script vai ficar no servidor e várias pessoas poderão imprimir o relatório pode ser que em algum momento esse erro ocorrerá. Você tem alguma idéia que possa me ajudar?

    Roseane

    Utilizando Mozilla Firefox Mozilla Firefox 3.6.18 no Ubuntu Linux Ubuntu Linux

Deixe um Comentário

O seu endereço de email não será publicado Campos obrigatórios são marcados *

*

Você pode usar estas tags e atributos de HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">