Um dúvida muito recorrente em fóruns concerne a erros com acentuação, quando palavras como “atenção” são exibidas como “aten??o”. Ou ficam com caracteres estranhos, como na imagem acima.
A solução geralmente é muito simples: padronizar as codificações de arquivos, do banco de dados e do HTML.
A melhor codificação a ser usada é a UTF-8, que suporta diversos idiomas, e tem sido adotada como codificação padrão em diversas aplicações.
E importante manter todas as codificações iguais, ou seja, todas em UTF-8. Para um site, é preciso atentar para as seguintes codificações:
Codificação do arquivo propriamente dito
É a codificação do arquivo dentro do sistema operacional. Ela pode ser modificada por meio do seu editor de textos (Sublime, Notepad++, Eclipse, Netbeans e outros). Também é possível alterar a codificação de um arquivo com o comando iconv
, em ambientes Linux ou Mac OS X, da seguinte forma:
$ iconv -f codificacao_original -t utf-8 arquivo > arquivo_utf8 |
Para mais detalhes sobre como usar o comando iconv
, veja este tutorial.
UTF-8 Sem BOM
O BOM (Byte Order Mark, ou Marca de Ordem de Byte) é uma sequência de
caracteres que é inserida no início de um arquivo para definir a ordem dos bytes. Isso é uma razão de um dos principais problemas com o uso de sessões e cookies, como descrevo aqui.
Por isso use sempre UTF-8 sem BOM e não terá problemas.
Codificação do HTML
A codificação do HTML é definida por meio de meta tag ou da função header(), do PHP.
Definição por meio de meta tag, para HTML 5:
<meta charset="utf-8" /> |
Definição por meio de meta tag, para HTML 4 e XHTML:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
Definição por meio da função header(), do PHP:
1 | header( 'Content-Type: text/html; charset=utf-8' ); |
Codificação do banco de dados e das tabelas
Se a sua aplicação usa um banco de dados, ele precisa, também, estar na codificação usada – UTF-8 no nosso caso. Ela é definida quando se criam o banco de dados e as tabelas. Por exemplo, com MySQL, podemos definir as codificação assim:
Codificação do banco de dados:
CREATE DATABASE bancodedados DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; |
Codificação das tabelas:
CREATE TABLE tabela( id SMALLINT(5) UNSIGNED NOT NULL auto_incre3ment, nome VARCHAR(20) NOT NULL, sobrenome VARCHAR(50) NOT NULL, PRIMARY KEY (id) ) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; |
Assim, todos os campos do tipo string estarão na codificação utf8.
Migrando Dados Não-UTF-8 Para UTF-8
Muitas vezes, precisamos migrar os dados de um banco de dados que não está em UTF-8 para outro que está em UTF-8.
Se apenas fizermos um SELECT
em um e um INSERT
no outro, erros de codificação vão aparecer para todo lado. É necessário remover os caracteres não-utf-8. E a melhor forma que encontrei para fazer isso é utilizando a seguinte rotina:
$regex = <<<'END' / ( (?: [\x00-\x7F] # single-byte sequences 0xxxxxxx | [\xC0-\xDF][\x80-\xBF] # double-byte sequences 110xxxxx 10xxxxxx | [\xE0-\xEF][\x80-\xBF]{2} # triple-byte sequences 1110xxxx 10xxxxxx * 2 | [\xF0-\xF7][\x80-\xBF]{3} # quadruple-byte sequence 11110xxx 10xxxxxx * 3 ){1,100} # ...one or more times ) | ( [\x80-\xBF] ) # invalid byte in range 10000000 - 10111111 | ( [\xC0-\xFF] ) # invalid byte in range 11000000 - 11111111 /x END; function utf8replacer($captures) { if ($captures[1] != "") { // Valid byte sequence. Return unmodified. return $captures[1]; } elseif ($captures[2] != "") { // Invalid byte of the form 10xxxxxx. // Encode as 11000010 10xxxxxx. return "\xC2".$captures[2]; } else { // Invalid byte of the form 11xxxxxx. // Encode as 11000011 10xxxxxx. return "\xC3".chr(ord($captures[3])-64); } } preg_replace_callback($regex, "utf8replacer", $text); |
Esse código eu retirei deste post no StackOverflow.
Problemas persistentes
Se você usava codificações diferentes, e, depois, modificou apenas a codificação do banco de dados, as acentuações, provavelmente, continuarão erradas. Não basta apenas mudar a codificação, nesse caso; será necessário passar os dados para outra tabela, que esteja, inicialmente, na codificação correta. É possível fazer essa transferência de dados por meio de apenas uma consulta. Para MySQWL, por exemplo, é possível usar um INSERT INTO… SELECT.
No meu Guia Gratuito de 15 Dicas e Boas Práticas de PHP falo mais sobre isso. Além dessa, são outras 14 dicas que vão deixar seus sistemas PHP mis estáveis, seguros e eficientes. Clique aqui para baixar o guia gratuito agora mesmo.
Essa e inúmeras outras dicas e técnicas eu abordo com mais detalhes no meu Curso ULTIMATE PHP. Estude PHP desde o básico, de forma 100% prática. Aprenda como se tornar um excelente programador, reconhecido e valorizado. Clique Aqui e Conheça o Curso Agora Mesmo!
Roberto Beraldo
Latest posts by Roberto Beraldo (see all)
- Não Tenha Preguiça de Ler! - 25/04/2016
- Como Atualizar Scripts PHP de MySQL Para MySQLi - 29/10/2015
- Como usar PDO com banco de dados MySQL - 10/09/2015