Um cliente me forneceu o backup de seu banco de dados MySQL, porém, ao importá-lo alguns caracteres estranhos substituíam os esperados acentos. Palavra com “Olá” estava escrita como “Olá”, “Termos de Serviço” estava como “Termos de Serviço”.
O Problema obviamente era de codificação (charset, collation) utilizada entre os dois bancos: o Banco original estava no padrão Latin 1 (latin_swedish_ci) enquanto o outro estava em UTF8 (utf8_general_ci). Caracteres como “ç”, “ã”, “á” e etc pertence ao padrão Latin 1 (ISO-8859-1); o padrão UTF8 por utilizar menos dados para armazenar cada caractere é obrigado a representar as letras acentuadas (e a cedilha) utilizando dois caracteres, o que vem a causar este problema.
A solução óbvia para esta falha seria modificar o charset do banco de dados e da tabela. Mas isto não solucionou o meu caso. Resolvi então utilizar uma abordagem menos rebuscada: criei um script PHP para atualizar cada linha na tabela do banco de dados convertendo-as para o padrão desejado.
Para isso utilizei a função mb_convert_encoding:
<?php set_time_limit(0); // Tempo máximo de execução: sem limite (0). // ---------------------------------------------------------------------- // Configurações // ---------------------------------------------------------------------- define("SETTINGS_SGBD_HOST", "localhost"); define("SETTINGS_SGBD_PORT", "3306"); define("SETTINGS_SGBD_USER", ""); define("SETTINGS_SGBD_PASSWORD", ""); define("SETTINGS_SGBD_DATABASE", ""); define("SETTINGS_SGBD_FIX_TABLE", ""); define("SETTINGS_SGBD_FIX_FIELD", ""); // ---------------------------------------------------------------------- // Conectar ao Banco de Dados // ---------------------------------------------------------------------- $lobj_databaseObject = mysql_connect(SETTINGS_SGBD_HOST.":".SETTINGS_SGBD_PORT, SETTINGS_SGBD_USER, SETTINGS_SGBD_PASSWORD); mysql_select_db(SETTINGS_SGBD_DATABASE); if ( $lobj_databaseObject == false ) exit; mysql_set_charset('latin1', $lobj_databaseObject); // ---------------------------------------------------------------------- // Atualiza a tabela corrigindo a codificação // ---------------------------------------------------------------------- $lstr_SQLQuery = "SELECT ".SETTINGS_SGBD_FIX_FIELD." FROM ".SETTINGS_SGBD_FIX_TABLE; $lobj_recordsetFields = mysql_query ($lstr_SQLQuery, $lobj_databaseObject); if ( mysql_num_rows($lobj_recordsetFields) > 0 ) { while ($lobj_rowTerm = mysql_fetch_object( $lobj_recordsetFields )) { $lstr_fixFieldContent = eval( "return $lobj_rowTerm->".SETTINGS_SGBD_FIX_FIELD.";"); $lstr_SQLQuery = "UPDATE ".SETTINGS_SGBD_FIX_TABLE." SET ".SETTINGS_SGBD_FIX_FIELD." = '".mb_convert_encoding($lstr_fixFieldContent, 'ISO-8859-1', 'UTF-8')."' WHERE ".SETTINGS_SGBD_FIX_FIELD." LIKE '$lstr_fixFieldContent'"; mysql_query ($lstr_SQLQuery, $lobj_databaseObject); } } // ---------------------------------------------------------------------- // Desconectar do Banco de Dados // ---------------------------------------------------------------------- mysql_close ( $lobj_databaseObject ); ?>
Para utilizar o script acima, modifique as constantes:
Lembre-se: Este script deve ser executado apenas uma vez! Na segunda execução o script tentará converter novamente os textos para Latin1, removendo todas as letras que estão acentuadas.
O que você achou? Tem alguma sugestão para resolver este problema ou algo a dizer que complemente este artigo. Deixe seu comentário!
Até mais!
Natural de Salvador-BA, é graduado em Analise de Sistemas pela Universidade Católica do Salvador (2003), e especialista em Engenharia de Software pela Universidade Salvador (2010). Exerce atualmente o cargo de Analista Judiciário na Justiça do Trabalho.
Muito bom cara! Resolveu meu problema
e como saber qual campo da tabela e a propria tabela está em látin1?
Seu script é excelente, mas tenho uma dúvida, como eu poderia fazer para aplicar geral no banco, sem eu ter que ficar preenchendo o nome da tabela mais o campo, ou seja, que ele verificasse em todas as tabelas e em todos os campos. Teria como você me ajudar ?
Para arrumar a base:
UPDATE tabela SET coluna1 = CONVERT(CAST(coluna1 as BINARY) USING utf8), coluna2 = CONVERT(CAST(coluna2 as BINARY) USING utf8);
ALTER TABLE `tabela` CHARACTER SET utf8 COLLATE utf8_general_ci ROW_FORMAT = DYNAMIC;
Para os arquivos PHP:
header(‘Content-Type: text/html; charset=utf-8’);
mysql_query(“SET NAMES ‘utf8′”);
mysql_query(‘SET character_set_connection=utf8’);
mysql_query(‘SET character_set_client=utf8’);
mysql_query(‘SET character_set_results=utf8’);
NO HTML: