O output buffering do PHP é uma daquelas coisas que ninguém percebe — até o dia em que ela destrói o comportamento do seu sistema em produção.
No meu caso, era um dashboard com rotas amigáveis e múltiplos filtros. O fluxo funcionava perfeitamente quando o filtro de cliente ficava vazio, mas bastava escolher “all” e tudo travava.
Nenhum erro de lógica, nada no log, apenas um carregamento eterno e o navegador parado.
O sintoma era estranho: o HTML principal renderizava, mas o JavaScript, responsável por reconstruir a URL e atualizar os gráficos, simplesmente não rodava. Quando o display_errors estava ativo, tudo voltava a funcionar — o que é o tipo de coisa que nenhum desenvolvedor quer admitir.
O problema estava no timing.
O PHP, por padrão, mantém o buffer de saída aberto até o final do script.
Isso significa que o navegador não recebe o HTML imediatamente, e alguns scripts podem tentar interagir com elementos que ainda não chegaram.
Se o fluxo de saída estiver comprimido, empacotado por mod_deflate ou output_buffering, o atraso pode ser ainda maior.
A correção foi simples, (mas não significa que foi rápida e pacífica =/) e contraintuitiva: forçar o envio do conteúdo no ponto exato em que o PHP termina a renderização do cabeçalho da página, antes do JavaScript que depende desse conteúdo.
$clienteGet = trim((string)(get(5) ?? ''));
$clienteGet = $clienteGet === '' ? 'all' : $clienteGet;
// --- NÃO MEXER ---
// Mantém o sistema vivo e sincronizado com o navegador.
// O flush força o envio imediato do HTML parcial antes dos scripts JS rodarem.
// Sem isso, o buffer do PHP atrasa a renderização e quebra os filtros/URLs.
// Repita comigo: NÃO MEXER NESSE TRECHO.
if (ob_get_level() > 0) {
@ob_flush();
}
@flush();
Essas duas linhas instruem o PHP a esvaziar o buffer atual e enviar os dados imediatamente ao cliente HTTP.
Em sistemas que misturam renderização de servidor e execução de scripts assíncronos, isso evita que o navegador fique “esperando o resto da página” antes de processar eventos, redirecionamentos ou requisições AJAX.
Vale lembrar que ob_flush() e flush() não são mágicos:
- Eles só funcionam se não houver buffering adicional em nível de servidor (ex: Nginx, Apache, FastCGI).
- E devem ser usados apenas quando o tempo de entrega do HTML interfere na execução do front-end, nunca como remendo genérico.
Mas quando o sintoma é esse — comportamento diferente entre debug ligado e desligado — pode apostar: é o buffer segurando o show.
“Nem todo bug é um erro. Às vezes, é apenas o PHP sendo educado demais pra enviar o que você pediu.”
