Função PHP ob_gzhandler(): Tudo o Que Você Precisa Saber
Aprenda como usar a função ob_gzhandler() do PHP para compactar saídas com gzip, reduzir largura de banda e acelerar o carregamento das suas páginas.
Compactar HTML, CSS ou JSON antes de enviá-los pelo servidor reduz a largura de banda e faz as páginas carregarem mais rapidamente. A função nativa ob_gzhandler() do PHP é uma forma pronta para fazer isso dentro do seu script: você a passa para o buffer de saída e ela compacta com gzip tudo o que o script ecoa — mas somente quando o navegador indica que consegue descompactar. Este artigo cobre sua sintaxe, um exemplo completo, como ela negocia com o cliente, os problemas que costumam surgir e quando usá-la em vez de deixar o servidor cuidar da compactação.
O Que a Função ob_gzhandler() Faz
ob_gzhandler() é um callback criado para ser passado para ob_start(). Você nunca a chama diretamente — em vez disso, o sistema de buffer de saída a chama com o conteúdo em buffer como argumento, e ela retorna os bytes compactados (ou, quando a compactação não é possível, sem modificação).
Antes de compactar, ela inspeciona o cabeçalho Accept-Encoding da requisição e escolhe o melhor esquema suportado:
- Se o cliente suporta gzip, compacta com gzip e define
Content-Encoding: gzip. - Se o cliente suporta apenas deflate, usa deflate.
- Se o cliente não suporta nenhum dos dois, retorna o conteúdo sem alteração e
ob_start()falha (retornafalse), então a resposta é enviada sem compactação.
Como ela define os cabeçalhos de resposta Content-Encoding e Vary automaticamente, você precisa registrá-la antes que qualquer saída seja enviada — veja headers_sent() se receber um erro de "cabeçalhos já enviados".
Sintaxe
ob_start("ob_gzhandler");ob_gzhandler() recebe dois parâmetros internamente ($buffer e $mode), mas você nunca os fornece — o motor de buffer o faz. Você apenas registra a string "ob_gzhandler" como nome do callback.
Um Exemplo Completo
<?php
ob_start("ob_gzhandler");
echo "This will be compressed using gzip compression";
ob_end_flush();
?>Aqui, ob_start() abre um buffer de saída com ob_gzhandler() como seu handler, o echo escreve nesse buffer em vez de ir direto para o cliente, e ob_end_flush() fecha o buffer e envia seu conteúdo (agora compactado). Do ponto de vista do visitante nada muda — o navegador descompacta a resposta de forma transparente — mas menos bytes trafegam pela rede.
Fallback para Clientes que Não Suportam gzip
ob_start("ob_gzhandler") retorna false quando o cliente não anuncia suporte a gzip ou deflate. Se você ignorar isso, nenhum buffer é iniciado e o seu ob_end_flush() posterior emitirá um aviso. Verifique o valor retornado e use um buffer simples como fallback:
<?php
if (!ob_start("ob_gzhandler")) {
ob_start(); // plain buffer, no compression
}
echo "Served either compressed or uncompressed, but always buffered.";
ob_end_flush();
?>Definindo o Nível de Compactação
ob_start() não aceita um nível de compactação — ob_gzhandler() usa o padrão do zlib (controlado pela configuração INI zlib.output_compression_level, padrão -1). Para forçar um nível específico de 1 (mais rápido, menor compactação) a 9 (mais lento, menor tamanho), ignore ob_gzhandler() e use seu próprio callback com gzencode():
<?php
ob_start(function ($buffer) {
return gzencode($buffer, 9);
});
echo "Compressed at the maximum level.";
ob_end_flush();
?>Note que esse callback personalizado não negocia Accept-Encoding nem define Content-Encoding: gzip por você — ob_gzhandler() faz ambos automaticamente. Se você criar o seu próprio, deve enviar esses cabeçalhos manualmente, o que explica por que ob_gzhandler() continua sendo conveniente para o caso comum.
ob_gzhandler() vs. zlib.output_compression
O PHP oferece uma segunda forma, ainda mais simples, de compactar a saída: a diretiva INI zlib.output_compression. Defina-a como On (ou um limite em bytes) e o PHP faz o gzip de toda a resposta sem nenhum código:
zlib.output_compression = OnAs duas abordagens são mutuamente exclusivas — habilitar zlib.output_compression enquanto também chama ob_start("ob_gzhandler") gera um aviso e não produz dupla compactação útil. Prefira zlib.output_compression quando puder editar o php.ini ou usar ini_set(), e reserve ob_gzhandler() para casos em que você precisa disso dentro de um script sem controle sobre a configuração.
Problemas Comuns
- Não aninhe camadas gzip. Combinar
ob_gzhandler()com compactação no nível do servidor (Nginx/Apachegzip) ou comzlib.output_compressionpode gerar respostas corrompidas, com codificação dupla. - Registre-a primeiro. Qualquer
echoanterior, espaço em branco antes de<?phpou BOM no arquivo envia cabeçalhos prematuramente e quebra a compactação. - Não use para binários já compactados. Fazer gzip de JPEGs, PNGs ou ZIPs desperdiça CPU com ganho de tamanho quase nulo.
- Requer a extensão zlib.
ob_gzhandler()exige que o PHP seja compilado com zlib (quase sempre é, mas vale saber em builds mínimas).
Conclusão
A função ob_gzhandler() fornece uma forma simples e independente de compactar a saída PHP com gzip: registre-a como callback para ob_start(), e ela negocia a codificação e define os cabeçalhos por você. Em configurações modernas, porém, a compactação no nível do servidor (Nginx, Apache) ou um CDN que cuide do gzip/brotli costuma ser preferível — isso descarrega a CPU do PHP e também compacta ativos estáticos. Conhecer ob_gzhandler() ainda é importante para bases de código legadas e scripts onde você não pode alterar a configuração do servidor. Para uma visão mais ampla sobre buffers, consulte a visão geral do Controle de Saída PHP.