Feed e Twitter

Feed RSS Twitter

Busca

Por Lustosa em 04/01/2009 às 22:20

Hoje em dia, é incrível como ainda temos pessoas tendo problemas com acentuação, e ainda pior, ao invés de se resolver o problema da forma correta, inventam várias gambiarras pra “deixar funcionando”, mesmo que não seja da forma certa.

Antes de mostrar os problemas que são normalmente encontrados, um pouco de história pra descobrirmos porque existem várias codificações, e que elas não estão aí só pra atrapalhar a nossa vida.

A muito, muito tempo atrás…

Todos sabemos que os computadores manipulam bits, e que para facilitar a nossa vida, os agrupam em bytes, que são conjuntos de 8 bits. Como cada bit pode valer 0 ou 1, temos, para um byte, 256 combinações diferentes. Logo, 1 byte tem a capacidade de armazenar um número de 0 a 255.

Como os computadores no passado operavam na língua inglesa, foi adotado o padrão ASCII (lê-se ásqui). Este padrão de codificação define 128 caracteres, sendo alguns de controle e outros tantos para codificar letras, números e alguns sinais.

Como só são necessários 128 valores para representar toda a gama de caracteres pela codificação ASCII, ficamos com a metade da capacidade de armazenamento do nosso byte sem uso. Chamamos este formato de codificação também de 7-bit, pois precisamos de apenas 7 bits para codificar 128 valores.

Entram em cena as extensões

Conforme foi sendo necessário se colocar caracteres e símbolos extras, como por exemplo, letras gregas e caracteres internacionais (cê-cedilha, a-com-til, etc), resolveu-se o problema da forma mais simples possível.

Como temos a metade do byte inutilizada, porque não usar estes 128 valores que estão “sobrando” para armazenar outros caracteres? Pois foi exatamente isto que foi feito. Definiram símbolos que seriam adicionados neste espaço, e nasceram as “tabelas ascii estendidas”, ou seja, são completamente compatíveis com o padrão ASCII (pois os primeiros 128 valores não mudam).

O grande problema desta solução está no fato de que no mundo inteiro, existem muito mais que 128 caracteres e símbolos. Daí, cada região passou a trabalhar com sua própria tabela ASCII estendida. No ocidente, se usa a codificação ISO8859-1, que possui caracteres latinos, letras gregas. É usado em boa parte do mundo (Americas, Oceania, Europa ocidental e boa parte da Africa).

Outras regiões usam outras codificações, como por exemplo o KOI8-R, usado na Rússia. Esta codificação possui todo o alfabeto cirílico, utilizado naquela região.

Uma tremenda confusão

Com dezenas de codificações, muitos problemas passaram a ocorrer. Se tentar ler um documento codificado em ISO8859-1 usando outra tabela ASCII estendida que não seja a ISO8859-1, qualquer caractere que esteja na área estendida da tabela (acima dos 128 primeiros caracteres) irá aparecer trocado por outro. E como o computador não tem como saber qual é a codificação correta de um documento sem analisá-lo semanticamente (temos apenas uma grande seqüência de valores de 0 a 255), temos um grande problema formado.

Outro problema sério é a impossibilidade de se exibir um documento com caracteres de várias línguas diferentes, sem implementar algum tipo de gambiarra.

Unicode: seus problemas acabaram!

No meio disso tudo, nasce o Unicode, para resolver de vez todos os problemas relacionados a codificação de caracteres. A idéia é simples: ao invés de usar apenas 1 byte pra armazenar todos os caracteres, símbolos, figuras, etc (o que é logicamente impossível), porque não utilizar mais de 1 byte?

A codificação UTF-8 armazena caracteres em seqüências que variam de 1 a 4 bytes, mas mantendo a compatibilidade com o ASCII. Os primeiros 128 valores são idênticos.

Com o Unicode, surgem outros problemas que não irei discutir aqui, como por exemplo, um texto com 20 caracteres não irá ocupar necessariamente 20 bytes, e isto causa problemas de armazenamento em buffers, em disco, em estruturas de dados. Tudo deve estar preparado para receber possivelmente mais que os 20 bytes.

O fato é: Unicode é uma codificação universal, que comporta qualquer caractere existente até o momento (pelo menos até explorarmos o espaço e nos depararmos com algumas raças alienígenas).

De volta ao presente

Todos os problemas relacionados a acentuação hoje em dia decorrem de um erro simples: mistura de codificações. Simples assim.

Se é desejado um sistema completamente em UTF-8, então, todos os seus componentes devem estar operando em UTF-8. No caso de páginas web, os arquivos gerados devem estar em UTF-8, os bancos de dados devem estar preferencialmente em UTF-8, a conexão com os bancos de dados devem estar em UTF-8, e o servidor web deve informar ao navegador de que a página que ele está exibindo é UTF-8. Vou continuar usando o UTF-8 como exemplo, mas tudo isto vale para qualquer outra codificação. É só trocar onde estiver UTF-8 pela codificação que desejar.

As páginas

Os arquivos com o código HTML, ou o que quer que esteja sendo gerado, precisa estar codificado em UTF-8. Se ele não estiver, aparecerão caracteres esquisitos na tela, pois o navegador vai tentar ler a página como UTF-8, e o que vai estar lá não vai ser UTF-8. Acentos e símbolos extras vão ficar truncados.

Gambiarras surgem aqui. Ao invés de se resolver este problema da forma correta (mudando-se a codificação das páginas), muita gente prefere “dar um jeito”. Daí, temos no código chamadas para conversão de codificações, temos tradução de acentos em entidades html (ao invés de se colocar um “Ç”, coloca-se “Ç”). Claro que existem usos válidos para isto, mas o que mais vejo por aí é o uso disso para se contornar o problema e evitar a solução correta.

Banco de dados

Os bancos de dados deveriam preferencialmente estar em UTF-8, mas outras codificações também são possíveis. Isto acontece porque uma conexão feita com o banco pode operar em uma codificação, independente da forma como o banco guarda os dados internamente.

Explico: mesmo o banco de dados guardando tudo como ASCII internamente, se a conexão com o banco é feita em UTF-8, o banco “sabe” que precisa converter todos os dados antes de apresentá-los para a aplicação que os solicitou. O importante, no caso, é que a conexão seja efetuada com a codificação correta.

Cabeçalhos HTTP: importantíssimos!

E por último, de nada adianta tudo estar operando em UTF-8, e o servidor web dizer ao navegador: “aí, a página que vou te mostrar agora tá em ISO8859-1, ok?”. Daí o navegador tenta ler a página como ISO8859-1, e o resultado são vários caracteres duplos onde deveríamos ver acentos.

A forma correta de se fazer isto, é fazer com que o servidor envie o cabeçalho Content-type de forma correta, informando o tipo MIME do dado que está sendo servido, assim como a codificação utilizada.

Por exemplo, para páginas HTML, o servidor poderia enviar o seguinte cabeçalho:

Content-type: text/html; charset=utf-8

Uma gambiarra que se usa muito neste ponto é colocar o seguinte código no HTML:

<meta http-equiv="Content-type" content="text/html; charset=utf-8" />

Esta forma, embora funcione em alguns casos, deve ser evitada, pois o navegador só irá considerá-la se o servidor web não informar a codificação e se o navegador não tiver alguma preferência marcada. Ou seja, depende de fatores externos, e nem sempre será honrada.

Conclusão

Eu, pessoalmente, uso UTF-8 para tudo. Acho que já passou da hora desta codificação ser adotada por todos. Não vejo motivo hoje em dia para se continuar usando o obsoleto ISO8859-1 (também conhecido como “Latin-1″) ou outras codificações, visto que o UTF-8 engloba todas elas.

Tudo isto é independente da linguagem utilizada. No caso, citei a web porque é um campo onde tenho muita familiaridade, mas se aplica em qualquer situação.

E se a experiência contar, depois do dia que passei a usar UTF-8 para tudo, nunca mais tive problemas com acentuação. Só me restam as lembranças deste passado sombrio.

Artigos relacionados

Arquivado em programação
Tags: ,

Feed RSS para os comentários deste artigo.


4 comentários em “Problemas com acentuação?”

  1. Vilson comentou:

    Olá, gostaria de saber então, qual o tipo de caracteres usar no banco de dados, incluindo campos text/blob, o formato com acento será guardado direto no banco ou no será guardado como tags tipo á para “á” ?

    Atualmente utilizo utf-8 mais há algum tempo atrás utilizava o iso-8859-1, estou tentanto colocar um padrão em meus projetos, como ma base de dados, venho utilizando utf8_general_ci.

    É certo isso ?

    Abraço, ótimo post!

  2. Bruno Lustosa comentou:

    Oi, Vilson. Recomendo fazer o que você faz, usar utf-8 para tudo.
    Internamente, a base de dados irá guardar as sequencias unicode normais, nada de tradução para entidades html.
    Fazendo tudo em utf-8 (ou tudo em iso8859-1), você evita os problemas. A grande vantagem do utf-8 é o suporte a mais que 256 “caracteres” diferentes. Mas tem que usar em tudo: banco de dados, conexão, cabeçalho da página, e na página em si.
    Não existe a menor necessidade de se colocar os acentos na página como entidades html, á por exemplo. Um simples “á” é interpretado corretamente pelo navegador se o cabeçalho estiver ok.
    Abraço!

  3. Rafael comentou:

    Valeu pela dica funcionou

  4. mrguz comentou:

    Olá Bruno, percebo, não só pelo seu comentário, bem como pelo otimo post que você deve ter boa experiencia na area. eu sou mais um tipo de entusiasta no assunto apesar de ja ter feito boas coisas.
    Eu realmente não domino nada sobre as codificações e na sua citação: “Mas tem que usar em tudo: banco de dados, conexão, cabeçalho da página, e na página em si.”.
    Fiquei imaginando como fazer isso, mas, realmente não sei como. E olha só como são as coisas:
    Estou justamente com esse problema de erro nas acentuações.
    Por isso lhe pergunto:
    Como faço para declarar o utf-8 em tudo como na sua citação? Estou quase desistindo…
    Será que poderia disponibilizar um exemplo para cada situação?
    Muitissimo obrigado!
    Mrguz.


Copyright 2009 Ataraxia!   Sinopse