Remover o BOM de arquivos em UTF-8

BOM - Byte Order Mark - é um identificador para arquivos em UTF-8/16/32 (vou ignorar o 16 e o 32 aqui), teoricamente para dizer ao interpretador/editor que se trata de um conteúdo codificado como UTF-8, mas o fato é que, em quase todas as circunstâncias, ele é dispensável.

Caso o seu interpretador não reconheça a codificação, você poderá ver algo como "" no início de arquivos em utf8 - na verdade antes do início do arquivo, o que faz com que esse código só seja visível em caso de erro - normalmente ele só será visível num editor hexadecimal.

Mas qual é o problema? O  meu problema foi em PHP, usando include para adicionar um conteúdo em UTF-8. A questão é que, se tivermos incluído um arquivo em UTF-8 (com o BOM) antes de usar funções como header(), veremos aquele conhecido erro que diz que uma função que manipula os cabeçalhos HTTP (header e outras) não pôde ser executada porque a saída já havia iniciado, portanto os cabeçalhos já haviam sido enviados. Mas você não mandou imprimir nada!

Bem, aí temos que lembrar que o PHP não é um interpretador de arquivos de texto, portanto o BOM no início do arquivo é apenas algo que está fora do escopo da TAG <?php ... ?>. Se temos um arquivo assim:

  1. <?php $something = 'anything'; ?>
  2. <?php print_to_file($something); ?>

Esse arquivo não imprime nada, certo? Errado, ele imprime (implicitamente) uma quebra de linha que está entre ?> e <?php - porque tudo o que estiver fora do escopo das tags PHP é HTML, que é enviado imediatamente para o browser. Isso é o mesmo que imprimir com print ou echo ou outra. Ok, então corrigi o arquivo e agora ele está assim:

  1. <?php $something = 'anything';
  2. print_to_file($something); ?>

Perfeito. Então salvo em UTF-8 e... erro! por que? veja como ficou o arquivo para o PHP:

  1. <?php $something = 'anything';
  2. print_to_file($something); ?>

A solução é remover o BOM e, provavelmente, isso não fará a menor diferença - pra mim não fez nenhuma. Mas como remover o BOM? Pensei, se dá pra ver num editor hexadecimal, dá pra deletar... baixei e instalei o PsPad (um editor excelente para programadores) mas não pude remover o danado, não dá (ou eu não soube).
Bem, achei um script em Perl que fazia isso e com base nele, fiz um em PHP que funcionou perfeitamente aqui. Pode ser que seja útil para você.

  1. <?php
  2. // substitua pelo caminho para o arquivo que deseja limpar
  3. $file = "C:/wamp/www/wordpress/wp-content/themes/basic-gray/lib/langs.php";
  4. print removeUTF8BOM($file) ? 'BOM removido!' : 'Não havia BOM a ser removido...';
  5.  
  6. function removeUTF8BOM($fil) {
  7. $newcontent = '';
  8. $first = false;
  9. $fh = fopen($fil, 'r');
  10.   while($part = fread($fh, 1024)) {
  11.     if(!$first) {
  12.       if(preg_match('/^\xEF\xBB\xBF/', $part)) {
  13.       $newcontent = preg_replace('/^\xEF\xBB\xBF/', "", $part);
  14.       } else {
  15.       fclose($fh);
  16.       return false;
  17.       }
  18.     $first = true;
  19.     } else $newcontent .= $part;
  20.   }
  21. fclose($fh);
  22. $fh = fopen($fil, 'w');
  23. fwrite($fh, $newcontent);
  24. fclose($fh);
  25. return true;
  26. }
  27. ?>
Categoria:Funções
Tags: ,
Permalink | Faça um comentário ou um trackback.

3 Comentários

  1. Luis
    Em 2 de dezembro de 2009 às 12:11 | Permalink

    Queria falar com o Cau Guanabara se puder entrar em contato via msn eu agradeço, conheci voce pelo chongar que fez o template do site deles.
    Aguardo uma resposta.

  2. Cleria Moreira
    Em 25 de agosto de 2011 às 12:54 | Permalink

    Parabéns pela solução!

    Perfeito. Executei e resolveu o problema!

  3. Em 20 de outubro de 2011 às 0:04 | Permalink

    MUITO BOM… PARABÉNS..
    Perdi dois dias atraz desse problema..
    rodei o scrpt. parece magica.. dei muita risada..

    fantástico..

    Obrigado..

Faça um comentário

Seu email nunca mostrado ou compartilhado. Os campos com * são obrigatórios

*
*