Parte 1 de 2 – MYSQL, PHP, ISO, utf8, utf8_general_ci, utf8_unicode_ci

Artigo 1

Artigo 2

Introdução

UTILIZE SEMPRE UFT8! O motivo é simples, essa codificação é rica em caracteres especiais, abrange muitas línguas, e é utilizada como padrão nos navegadores e bancos de dados.

Antes eu utilizava iso-8859-1 como padrão, mesmo inserindo libraries e components em uft8. Depois que migrei arquivos, bancos e tudo para uft8 minha vida melhorou.

Isso porque: no momento que a página começa a renderizar, ela já assume uma codificação (ou tenta detectá-la acaso não seja declarada, geralmente usa o padrão do servidor) o que pode gerar um desconforto já que haverá uma mistura de codificações nos seus arquivos e de terceiros.

Os problemas comuns da codificação

É muito comum quando estamos trabalhando com acentos nos depararmos com caracteres estranhos como por exemplo:

  • Algo semelhante a Ã© que representa o é, isto ocorre porque o caractere é unicode, mas a página está em iso-8859-1 (ou outro compatível).
  • E o sinal  um exemplo de situação é quando você usa um acentos compatíveis com iso-8859-1 em uma página que esta tentando processar UTF-8 devido ao Content-Type: ...; charset=utf8.

Para se usar UTF-8, você deve utilizar:

  • PHP scripts (me refiro aos arquivos no servidor e não a resposta do mesmo) salvos em “utf-8 sem BOM”
  • MySQL (ou outro tipo de banco de dados) com charset=utf-8
  • Preferencialmente defina usando PHP header('Content-type: text/html; charset=UTF-8');

Nota: A vantagem do UTF-8 é que você pode utilizar vários “idiomas” na sua página com caracteres que não são suportados pelo “iso-8859-1”.

Sobre o iso-8859-1

Eu recomendo usar iso-8859-1 se o seu site for “100% em Português” e você não necessite de “codificações extras” (como por exemplo emojis), no entanto mesmo sendo em Português você deve pensar em talvez migrar pro utf-8, um dos motivos é que em junho de 2004, o grupo de desenvolvimento da ISO/IEC responsável por sua manutenção declarou o fim do suporte a esta codificação, concentrando-se no UCS e no Unicode.

Fonte: http://pt.wikipedia.org/wiki/ISO_8859-1

Se decidir usar UTF-8 no seu site/projeto, recomendo seguir os seguintes passos:

Scripts PHP com UTF-8 sem “BOM”

Nota: leia sobre isto em http://en.wikipedia.org/wiki/UTF-8#Byte_order_mark (Inglês)

Você deve salvar todos scripts PHP (até os que você usará com includerequire, etc) em utf-8 sem “BOM”, você pode utilizar softwares como SublimeText ou notepad++ para converter os arquivos:

  • Usando notepad++:utf8 sem bom notepad++
  • Usando Sublime Text:utf8 sublime sublimetext
  • Usando Eclipse vá até Window > Preferences > General > Workspace > Text File Encoding:netbeans

Nota: que arquivos com extensão .js ou .css que usam acentos no conteúdo também ser salvos com a mesma codificação que as páginas, da mesma maneira que foi usado para salvar os documentos descritos acima, eventualmente arquivos .svg podem ser embarcados então se eles tiverem qualquer acentuação ou caractere diferente também devem ser salvos com a mesma codificação da página

MySQL com UTF-8

Para criar uma tabela em UTFf-8 no MySQL você deve utilizar algo como:

CREATE TABLE minhatabela (
   id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
   titulo varchar(300) DEFAULT NULL
) ENGINE=InnoDB CHARACTER SET=utf8 COLLATE utf8_unicode_ci;

Se as tabelas existem, então primeiro faça um BACKUP delas e depois, utilize um dos seguintes comandos (conforme a necessidade):

  • Converte banco de dados: ALTER DATABASE bancodedados CHARACTER SET utf8 COLLATE utf8_unicode_ci;
  • Converte uma tabela especifica: ALTER TABLE minhatabela CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;

Além de criar as tabelas em UTF-8 é necessário definir a conexão como UTF-8.

Com PDO é necessário usar exec:

$conn = new PDO('mysql:host=HOST;dbname=BANCO;charset=utf-8', 'USUARIO', 'SENHA');
$conn->exec('SET CHARACTER SET utf8');//Define o charset como UTF-8

Com o mysqli é necessário usar mysqli_set_charset:

$mysqli = new mysqli('HOST', 'usuario', 'senha', 'banco');

if ($mysqli->connect_error) {
    printf('Erro de conexão: %s', $mysqli->connect_errno);
    exit;
}

/*
 * compatibilidade para to 5.2.9 e 5.3.0.
 */
if (mysqli_connect_error()) {
    printf('Erro de conexão: %s', mysqli_connect_error());
    exit;
}

if (false === $mysqli->set_charset('utf8')) {
    printf('Error ao usar utf8: %s', $mysqli->error);
    exit;
}

Com mysqli procedural:

<?php
$link = mysqli_connect('HOST', 'usuario', 'senha', 'banco');

if (mysqli_connect_error()) {
    printf('Erro de conexão: %s', mysqli_connect_error());
    exit;
}

if (!mysqli_set_charset($link, 'utf8')) {
    printf('Error ao usar utf8: %s', mysqli_error($link));
    exit;
}

Definindo o charset da página

Você pode usar a tag <meta> para definir o charset, mas o recomendável é você fazer isto na resposta da requisição (resposta do servidor), definindo os “headers” (isto não quer dizer que você não deva utilizar <meta>).

Para isto, no PHP use a função header:

O motivo para se utilizar na resposta do servidor também é por causa do tempo de renderização da página quanto a resposta do servidor e páginas AJAX precisam também do charset definido por header();.

Nota: header(); sempre deve ir no topo do script antes de qualquer echoprint, ou outro tipo de exibição de conteúdo.

Em arquivos que a resposta deve ser HTML:

<?php
header('Content-Type: text/html; charset=UTF-8');

echo 'Conteudo';