Guia completo UTF-8 para desenvolvedores PHP: do banco ao navegador

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Por que seus acentos viram "Привет" e como corrigir isso de uma vez por todas

\n\n

Você já abriu seu site em PHP e, em vez do esperado "Olá, mundo!", viu algo como Привет, РјСЂСЂ!? Se sim, parabéns: você encontrou o clássico problema do UTF-8 all the way through. É aquela situação em que a codificação quebra em algum lugar entre o banco de dados e o navegador, e todo mundo culpa todo mundo.

\n\n

No Stack Overflow, essa questão já acumulou milhares de visualizações e centenas de respostas. Não é à toa. Mesmo desenvolvedores experientes às vezes se perdem nas configurações de codificação. Neste tutorial, vamos seguir uma receita passo a passo para alinhar PHP, MySQL e navegador, garantindo que o UTF-8 funcione em todos os lugares. Sem mágica — apenas configurações corretas.

\n\n

Passo 1. Banco de dados: a base da sua codificação

\n\n

Tudo começa no banco. Se seus dados no MySQL estão em latin1 ou cp1251 e você tenta exibi-los em UTF-8, o resultado serão caracteres estranhos. Mas mesmo que o banco esteja em UTF-8, há um detalhe: a codificação antiga utf8 no MySQL não suporta emojis nem alguns caracteres raros. A solução é o utf8mb4.

\n\n

1.1. Criando tabelas com a codificação correta

\n\n

Ao criar uma nova tabela, sempre especifique:

\n\n
CREATE TABLE artigos (\n    id INT AUTO_INCREMENT PRIMARY KEY,\n    titulo VARCHAR(255) NOT NULL,\n    conteudo TEXT NOT NULL\n) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
\n\n

Alternativamente, defina a codificação padrão para todo o banco de dados:

\n\n
ALTER DATABASE nome_do_banco CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
\n\n

Importante: utf8mb4_unicode_ci é o collation (regra de comparação). Ele processa corretamente todos os caracteres Unicode. Se você não precisa de ordenação multilíngue, utf8mb4_general_ci também funciona.

\n\n

1.2. Convertendo tabelas existentes

\n\n

Se você já tem dados em outra codificação, converta-os primeiro:

\n\n
ALTER TABLE artigos CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
\n\n

Mas cuidado: se a tabela já tinha dados em latin1, eles podem virar codificação dupla (ex.: Привет). Nesse caso, é preciso converter as colunas para binary e depois para utf8mb4. Essa é outra história; para simplificar, considere que você está começando do zero.

\n\n

Passo 2. Conexão PHP com o banco: configurando o PDO

\n\n

No PHP moderno, você usa PDO (ou mysqli). E há um ponto crítico: após conectar ao banco, é necessário definir explicitamente a codificação. Caso contrário, o PHP se comunicará com o MySQL na codificação padrão (geralmente latin1).

\n\n

2.1. String de conexão PDO correta

\n\n
$host = 'localhost';\n$dbname = 'seu_banco';\n$username = 'root';\n$password = '';\n\n$dsn = "mysql:host=$host;dbname=$dbname;charset=utf8mb4";\n\n$options = [\n    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,\n    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,\n    PDO::ATTR_EMULATE_PREPARES => false,\n];\n\ntry {\n    $pdo = new PDO($dsn, $username, $password, $options);\n} catch (PDOException $e) {\n    echo "Falha na conexão: " . $e->getMessage();\n}
\n\n

Repare no charset=utf8mb4 no DSN. Isso força PHP e MySQL a negociarem a codificação no nível da conexão.

\n\n

2.2. Método alternativo (se o DSN não funcionar)

\n\n

Às vezes, versões antigas do PHP ou servidores não leem o charset do DSN. Nesse caso, adicione após a conexão:

\n\n
$pdo->exec("SET NAMES 'utf8mb4'");
\n\n

Mas o primeiro método é preferível — é mais limpo e moderno.

\n\n

Passo 3. Cabeçalhos HTTP e HTML: dizendo a verdade ao navegador

\n\n

Mesmo que o banco e o PHP estejam em UTF-8, o navegador pode achar que

Blogs

Book Recommendations