Double-encoding é quando texto UTF-8 é tratado como ISO-8859-1 e re-codificado. Resultado: "São Paulo" vira "São Paulo". Veja como detectar e corrigir.
O que é double-encoding
- Texto original:
São Paulo(UTF-8) - Sistema lê como ISO-8859-1:
São Paulo - Sistema re-codifica para UTF-8:
São Paulo(double-encoded)
Como detectar
No banco (Firebird)
-- Registros com padrão de double-encoding
SELECT nome FROM clientes
WHERE nome CONTAINING 'Ã' OR nome CONTAINING 'Â' OR nome CONTAINING 'ÃÂ'
Em PHP
// Detectar se string está double-encoded
function isDoubleEncoded(string $s): bool {
$decoded = mb_convert_encoding($s, 'ISO-8859-1', 'UTF-8');
return mb_check_encoding($decoded, 'UTF-8') && $decoded !== $s;
}
Como corrigir
Solução 1: Decodificar duas vezes
$texto = mb_convert_encoding($texto, 'ISO-8859-1', 'UTF-8'); // primeira decodificação
$texto = mb_convert_encoding($texto, 'ISO-8859-1', 'UTF-8'); // segunda (se necessário)
Solução 2: Corrigir no banco
-- Atualizar registros com double-encoding (Firebird)
UPDATE clientes
SET nome = CAST(nome AS VARCHAR(100) CHARACTER SET ISO8859_1)
WHERE nome CONTAINING 'Ã';
Solução 3: Prevenir na origem
Sempre declare o charset na conexão:
$pdo = new PDO('firebird:dbname=localhost:/db.fdb;charset=UTF8', $user, $pass);
E no HTML:
<meta charset="UTF-8">
Checklist de prevenção
- Banco de dados com charset definido (UTF8 ou ISO8859_1)
- Conexão PDO com charset explícito
- HTML com
<meta charset="UTF-8"> - Headers HTTP com
Content-Type: text/html; charset=utf-8 - Arquivos PHP salvos em UTF-8 sem BOM
Precisa gerar queries para detectar e corrigir encoding no seu banco? Descreva o problema em português no Sqlify.
Conclusão
Double-encoding é silencioso e difícil de detectar. A melhor defesa é declarar charset em todas as camadas: banco, conexão, HTML e headers.