Arquivo da tag: UTF8

Problema de acentuação no MySQL: Latin1 x UTF8

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:

  • SETTINGS_SGBD_HOST: IP do servidor;
  • SETTINGS_SGBD_PORT: porta de conexão do servidor;
  • SETTINGS_SGBD_USER: nome do usuário;
  • SETTINGS_SGBD_PASSWORD: senha do usuário;
  • SETTINGS_SGBD_DATABASE: banco de dados onde se localiza o problema;
  • SETTINGS_SGBD_FIX_TABLE: tabela onde se localiza o problema;
  • SETTINGS_SGBD_FIX_FIELD: campo onde se localiza o problema.
  • 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!