Se os acentos do seu site viraram símbolos estranhos — João em vez de João, informação em vez de informação —, o problema é de codificação de caracteres, e quase sempre aparece depois de exportar e importar um banco de dados. A causa mais comum é o mysqldump ou o phpMyAdmin gravando o arquivo num charset diferente do que o banco de destino espera.
A boa notícia: os dados não foram perdidos. Os bytes originais continuam lá — o que se perdeu foi a instrução de como interpretá-los. E na maioria dos casos dá para recuperar.
O que você vê diz onde está o problema:
João, informação | Texto UTF-8 sendo lido como latin1 — o caso mais comum |
Jo?o, informa??o | Dados já convertidos com perda. Precisa restaurar backup |
Jo�o | Byte inválido para o charset atual |
Emojis somem ou viram ??? | O banco está em utf8 e não em utf8mb4 |
Conteúdo
O que realmente está acontecendo
Um banco de dados não guarda letras — guarda números. Cada caractere é convertido em um ou mais bytes, e a tabela que define essa conversão é o charset (conjunto de caracteres).
O ã em UTF-8, por exemplo, ocupa dois bytes: C3 A3. Se um programa lê esses dois bytes achando que são latin1 — onde cada byte é um caractere —, ele exibe à e £. Daí o João.
Nada foi corrompido. Os bytes C3 A3 continuam exatamente onde estavam. O que falhou foi a instrução de como interpretá-los.
E é por isso que o problema costuma aparecer numa migração: o banco de origem falava um charset, o arquivo foi exportado noutro, e o banco de destino leu num terceiro. Basta um elo discordar para os acentos quebrarem.
Os quatro pontos onde o charset é definido
Esta é a parte que a maioria dos tutoriais não explica, e é por ela que o problema volta mesmo depois de “corrigido”: o charset é declarado em quatro lugares diferentes, e todos precisam concordar.
| Onde | O que define |
|---|---|
| Banco e tabelas | Como os dados são gravados em disco |
| Conexão | Como a aplicação e o banco conversam |
| Aplicação (PHP, WordPress) | Como o código trata o texto que recebe |
| Página HTML | Como o navegador exibe o resultado |
Um site pode ter o banco em UTF-8 e ainda assim mostrar acentos quebrados, se a conexão estiver em latin1. E o contrário também: banco em latin1 exibindo tudo certo, porque a conexão também está em latin1 — até o dia em que alguém exporta.
A regra é simples: use utf8mb4 nos quatro.
Atenção: utf8 no MySQL não é UTF-8
Um detalhe que resolve metade dos casos difíceis, e quase ninguém sabe.
Por razões históricas, o charset chamado utf8 no MySQL nunca foi o UTF-8 completo. Ele armazena no máximo 3 bytes por caractere, o que cobre acentos e a maioria dos idiomas, mas não cobre emojis nem alguns caracteres de línguas asiáticas.
O UTF-8 de verdade, com até 4 bytes, chama-se utf8mb4. Ele é o padrão desde o MySQL 8, mas bancos criados em versões anteriores costumam ter ficado no utf8 antigo.
Como isso aparece: os acentos funcionam normalmente, mas um emoji digitado num post ou num comentário some, vira ???, ou trunca o texto a partir dali.
Ao criar um banco novo, escolher tabelas ou definir a conexão, prefira sempre utf8mb4 com collation utf8mb4_unicode_ci. O utf8 antigo funciona para acentos, mas cria um problema latente que só aparece quando alguém usa um emoji — e aí a correção exige converter tudo de novo.
Como exportar sem quebrar os acentos
A causa mais frequente do problema. Duas formas de exportar, e o cuidado em cada uma:
Pelo phpMyAdmin: ao exportar, escolha o método Personalizado e confira o campo de conjunto de caracteres do arquivo. Ele deve estar em utf-8. No método Rápido, o phpMyAdmin usa o padrão do servidor — que nem sempre é o certo.
Pela linha de comando, o parâmetro é explícito:
mysqldump --default-character-set=utf8mb4 -u usuario -p nome_do_banco > backup.sql
E na importação, o mesmo cuidado:
mysql --default-character-set=utf8mb4 -u usuario -p nome_do_banco < backup.sql
Um detalhe que engana: abrir o arquivo .sql no Bloco de Notas e ver os acentos corretos não garante nada — o editor pode estar interpretando bem um arquivo que o MySQL vai interpretar mal. O que vale é o charset declarado na exportação.
Nosso guia sobre backup do banco pelo phpMyAdmin cobre o processo completo.
Como descobrir o charset atual do seu banco
Antes de corrigir, vale saber o que está configurado. No phpMyAdmin, abra a aba SQL e rode:
SELECT default_character_set_name, default_collation_name
FROM information_schema.SCHEMATA
WHERE schema_name = 'nome_do_banco';
E para ver tabela por tabela, que é onde as inconsistências aparecem:
SELECT table_name, table_collation
FROM information_schema.TABLES
WHERE table_schema = 'nome_do_banco';
É comum encontrar um banco declarado em utf8mb4 com tabelas antigas ainda em latin1 — resquício de migrações passadas.
Corrigindo um banco que já está com acentos quebrados
Aqui a ordem importa, e o primeiro passo não é negociável.
1. Faça backup antes de qualquer coisa. Conversão de charset é irreversível, e uma conversão feita na direção errada destrói os dados de vez — transformando um problema de exibição num problema real de perda. O mesmo vale para o erro de inicialização do MySQL no XAMPP, em que a pressa de “resolver” apagando arquivos é o que costuma destruir os bancos.
2. Identifique o cenário. Há dois, e a solução é diferente:
| Cenário | Como identificar | Solução |
|---|---|---|
| Só a leitura está errada | Você vê João. Os bytes estão corretos, a interpretação não | Ajustar o charset da conexão e das tabelas |
| Os dados já foram convertidos | Você vê Jo?o. Os bytes originais foram substituídos | Não há conversão que resolva — restaure um backup anterior |
Aquele segundo caso é importante e pouco dito: quando os acentos viram ?, a informação se perdeu de fato. O ponto de interrogação é o que o MySQL grava quando não consegue representar um caractere no charset de destino, e não há como saber qual letra estava ali.
3. Converta as tabelas, se for o primeiro cenário:
ALTER TABLE nome_da_tabela
CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
Repita para cada tabela. Um banco WordPress tem cerca de doze tabelas — o phpMyAdmin permite selecionar todas de uma vez e aplicar a operação em lote.
4. Ajuste a aplicação. No WordPress, o charset fica no wp-config.php:
define( 'DB_CHARSET', 'utf8mb4' );
define( 'DB_COLLATE', '' );
Em PHP puro com PDO, o charset vai na string de conexão: mysql:host=localhost;dbname=banco;charset=utf8mb4.
5. Confira o HTML. Mesmo com tudo certo no banco, uma página sem <meta charset="utf-8"> exibe acentos quebrados. Nosso guia sobre caracteres especiais e acentos no HTML cobre esse lado.
O caso específico do WordPress
Alguns pontos que só aparecem no WordPress:
A migração é o momento de risco. Ao mover o site, o banco de origem pode estar em latin1 e o de destino em utf8mb4. A exportação sem charset explícito é o que quebra tudo.
O wp-config.php manda no comportamento. Se o DB_CHARSET não bater com o charset real das tabelas, o WordPress grava certo e lê errado — ou o contrário.
Sites antigos costumam estar em latin1. Instalações de antes de 2015 foram criadas assim, e continuam funcionando até o dia da migração.
Plugins de migração ajudam. Ferramentas como Duplicator e All-in-One WP Migration cuidam do charset automaticamente — é um argumento a favor de usá-las em vez do processo manual, sobretudo para quem não domina o assunto.
Acentuação quebrada é o erro mais comum de migração feita às pressas. Na Homehost, a migração é gratuita e conduzida pela nossa equipe — arquivos, banco e e-mails, com o charset conferido antes de entregar. Servidor no Brasil, NVMe e suporte em português, a partir de R$ 7,90/mês.
Ver planos de hospedagemPerguntas frequentes
Por que os acentos do meu site viraram símbolos estranhos?
Porque o texto foi gravado num charset e está sendo lido em outro. O caso mais comum é conteúdo em UTF-8 sendo interpretado como latin1, o que transforma ção em ção. Os dados não foram perdidos: os bytes originais continuam no banco, e o que falhou foi a instrução de como interpretá-los.
Qual a diferença entre utf8 e utf8mb4 no MySQL?
O charset chamado utf8 no MySQL não é o UTF-8 completo — ele usa no máximo 3 bytes por caractere, o que cobre acentos mas não emojis nem alguns caracteres asiáticos. O utf8mb4 é o UTF-8 de verdade, com até 4 bytes. Use sempre utf8mb4.
Como exportar um banco MySQL sem quebrar a acentuação?
Pela linha de comando, use mysqldump --default-character-set=utf8mb4. No phpMyAdmin, escolha o método Personalizado e confirme que o conjunto de caracteres do arquivo está como utf-8 — o método Rápido usa o padrão do servidor, que nem sempre é o correto.
Meus acentos viraram pontos de interrogação. Dá para recuperar?
Não. O ponto de interrogação é o que o MySQL grava quando não consegue representar um caractere no charset de destino — a informação original foi substituída e não há como saber qual letra estava ali. A única saída é restaurar um backup anterior à conversão.
Como sei qual charset meu banco está usando?
No phpMyAdmin, a aba Operações do banco mostra o agrupamento (collation) atual. Para ver tabela por tabela, rode uma consulta em information_schema.TABLES filtrando pelo nome do seu banco — é comum encontrar bancos em utf8mb4 com tabelas antigas ainda em latin1.
Corrigi o banco mas os acentos continuam errados. Por quê?
O charset é definido em quatro lugares: banco e tabelas, conexão, aplicação e página HTML. Corrigir só um não basta — se a conexão continua em latin1, o problema persiste mesmo com as tabelas em utf8mb4. No WordPress, confira também o DB_CHARSET no wp-config.php.
Converter as tabelas para utf8mb4 é seguro?
A operação em si é padrão, mas é irreversível — e se os dados já estiverem em estado inconsistente, a conversão pode piorar. Faça backup do banco antes, sempre. Se a conversão der errado, o backup é a única forma de voltar atrás.
Por que isso acontece principalmente em migrações?
Porque a migração envolve três pontos onde o charset pode divergir: o banco de origem, o arquivo exportado e o banco de destino. Basta um deles discordar para os acentos quebrarem. Exportar e importar declarando utf8mb4 explicitamente evita o problema.
Veja também
Para entender o funcionamento do banco, veja o que é MySQL e os tipos de dados do MySQL. Sobre acentuação no lado do HTML, veja caracteres especiais e acentos. E se o site parou de conectar ao banco, veja erro ao estabelecer uma conexão com o banco de dados.
Conclusão
Acentuação quebrada assusta mais do que deveria: na maioria das vezes os dados estão intactos, e o que se perdeu foi só a instrução de como lê-los. O caminho é sempre o mesmo — descobrir em qual dos quatro pontos o charset diverge, alinhar todos em utf8mb4, e conferir se a aplicação e o HTML concordam. Duas coisas valem gravar: faça backup antes de qualquer conversão, porque ela é irreversível; e se os acentos viraram pontos de interrogação, não há conversão que resolva — ali a informação se foi, e só o backup traz de volta.