12 maio 2010

Padrões deveriam ser padrões

Há um mês tive com problemas de caracteres, aonde um sistema monta um pacote, com codificação:

se possui caracteres especiais -> unknown;
senão -> UTF-8;

Engraçado dessa forma, então como arquivos iso ou desconhecidos, cada caracter tem 1 byte e nos utf os caracteres especiais tem mais de um byte.
Cheguei ao seguinte código:

< ? php
  $file = fopen("arquivo.txt", 'rb');
  $string = '';
  $char = '';

  while (!feof($file)) {
    $char = fread($file,1);
    //echo mb_convert_encoding($char, 'utf-8') . ord($char) . "\n";
    switch (ord($char)) {
      case 138:
        $string .= 'ç';
      break;
     
      case 135:
        $string .= 'ã';
      break;
     
      default:
        $string .= $char;
      break;   
    }   
  }
  echo $string . "\n";
?>

Abre o arquivo, lê um carácter como decimal(ord), se encontrar o número ele converte, se não só imprime e vai fazendo isso enquanto chegar o fim do arquivo.

Para saber qual o decimal do carácter, caso não esteja nos padrões, descomente a aquela linha do mb_convert_encoding e comente o bloco do switch,mas se nos padrões é só conferir com a tabela ASCII.

Sabendo os decimais só ir colocando no case.

Porem, com isso só, não foi o suficiente, os caracteres foram lidos e convertidos, mas não estão visualmente aparecendo, então adicionei

< ! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
< html xmlns="http://www.w3.org/1999/xhtml">
    < head>
        < meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    < / head>
    < body>
    < / body>
< / html>

Pronto, dessa forma tive o problema resolvido, porém a conversão só vai acontecer em arquivos que não forem UTF-8, para saber então a codificação:

file --mime-encoding arquivo.txt

Agora se você sabe a codificação do arquivo, use:

iconv -f codificacao_de_origem -t codificacao_de_saida arquivo

exemplo: iconv -f iso-8859-1 -t utf-8 arquivo.txt

Ah! se padrôes fossem padrões.
...

obs.: existem alguns espaços no começo de cada linha do html, e na primeira linha do php para poderem ser visualizados aqui no blog.

Nenhum comentário: