Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

willian.abreu2726

Erro de Acentuação ao Gravar no MySQL

Recommended Posts

Boa noite pessoal!

Sou novo no fórum, então desde já peço desculpas se eu não souber exemplificar bem minha dificuldade e também agradeço muito por todos que puderem ajudar.

 

Pesquisei inúmeros posts a respeito deste assunto (Erro de Acentuação ao Gravar no MySQL) e segui muitas dicas, mas meu problema está persistindo.

 

Para facilitar a ajuda e o entendimento, criei um arquivo PHP de testes. (Seguindo algumas idéias que encontrei no fórum).

 

Vamos lá!

 

Situação do arquivo:

1. Este arquivo PHP está codificado e com <meta> em UTF-8.

2. O banco de dados e todas as tabelas estão com charset UTF-8 e collation utf8_unicode_ci

3. Fiz o teste com a função mysql_client_encoding() e retornou UTF-8

 

Obs.: Utilizei o EditPad para verificar a codificação do arquivo.

 

Erro:

Quando através do formulário envio um nome/palavra com acentos (ex.: João), está sendo gravado no banco de dados "Joòo". Mesmo estando gravado desta forma no banco de dados, ao resgatar do banco para exibir na página via php, o resultado impresso na página é "João".

 

Se eu utilizar o próprio terminal do mysql (S.O. Windows) para inserir o nome "João", logo é gravado corretamente. No entanto, se eu quiser exibir na página via php, o resultado impresso é "JoÆo".

Por curiosidade, fiz o teste enviando "JoÆo" pelo próprio formulário e foi gravado corretamente no banco de dados. rsrs

 

Abaixo segue o código:

<?php header("Content-Type: text/html; charset=UTF-8",true); ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="pt-br" xml:lang="pt-br">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Teste</title>
</head>
<body>
<form action="bd.php" method="post">
	Nome: 
	<input type="text" name="nome">
	<input type="submit" value="Enviar">
</form>
<?php
$op = $_GET['op'];
$host = "localhost";
$usuario = "root";
$senha = "admin";
$bd = "banco";

$nome = $_POST['nome'];

$conexao = mysql_connect($host, $usuario, $senha);
mysql_select_db($bd);
mysql_set_charset('utf8', $conexao);
ini_set('default_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');

	if ($nome) {
	$query = "insert into teste values (NULL, '".$nome."')";
	$resultado = mysql_query($query,$conexao);
	}
	
	$query = "Select * from teste order by idteste desc limit 10";
	
	$resultado = mysql_query($query,$conexao);
	while ($linha = mysql_fetch_array($resultado)){
		echo $linha[0]." - ".$linha[1]."<br>";	
		}
?>
</body>
</html>

Já utilizei utf8_encode() e utf8_decode() e eles até pioram a situação.

Também já tentei transformar tudo em ISO-8859-1, mas o erro é sempre o mesmo.

 

Já estou começando a pensar que pode ser alguma configuração do MySQL.

Bom gente, não sei mais como tentar resolver este problema.

Quero agradecer à colaboração de todos. :)

Compartilhar este post


Link para o post
Compartilhar em outros sites

Quando através do formulário envio um nome/palavra com acentos (ex.: João), está sendo gravado no banco de dados "Joòo". Mesmo estando gravado desta forma no banco de dados, ao resgatar do banco para exibir na página via php, o resultado impresso na página é "João".

 

Se eu utilizar o próprio terminal do mysql (S.O. Windows) para inserir o nome "João", logo é gravado corretamente. No entanto, se eu quiser exibir na página via php, o resultado impresso é "JoÆo".

esse trecho deu uma luz..

 

90% certeza de ser algo errado no banco.

 

Verifique:

 

- o collation das tabelas

veja as DDLs

 

- o mysql permite charsets distintos para o banco, tabelas e colunas. exemplo, o banco pode estar padrao utf8, a tabela com latin-iso e uma coluna na tabela pode estar como latin-swedish.

Verifique a integridade da DDL..

 

- Qual software utiliza para ler direto do banco ?

Workbench? Navicat ?

 

- como está a configuração mbstring do php ?

Execute o phpinfo() e veja a tabela "mbstring"

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom dia hinom, como vai? :)

Obrigado por responder a minha dúvida!

Demorei um pouquinho para responder porque estava analisando os itens que você mencionou.

 

Qual software utiliza para ler direto do banco? Workbench? Navicat?

Estou utilizando o Workbench, mas eventualmente utilizo o phpMyAdmin para 'conferir' o resultado das criações do Work.

 

O collation das tabelas. Veja as DDLs

Com relação as DDLs, abaixo segue o código de criação do banco de dados e das tabelas. No meu ver parece estar correto, mas estou postando aqui pois caso queira ver também.

SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL';

CREATE SCHEMA IF NOT EXISTS `banco` DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ;

USE `banco`;

CREATE  TABLE IF NOT EXISTS `banco`.`teste` (
  `idteste` INT(11) NOT NULL AUTO_INCREMENT ,
  `teste` VARCHAR(45) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci' NOT NULL ,
  PRIMARY KEY (`idteste`) )
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_unicode_ci;


SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
"o mysql permite charsets distintos para o banco, tabelas e colunas. exemplo, o banco pode estar padrao utf8, a tabela com latin-iso e uma coluna na tabela pode estar como latin-swedish. Verifique a integridade da DDL."
Eu não sabia deste detalhe! Ao verificar o banco de dados, percebi que as colunas não tinham charsets configurados. Fiz a alteração que já acompanha do código acima.
Como está a configuração mbstring do php? Execute o phpinfo() e veja a tabela "mbstring".
Bom, a única coisa que entendo é que o "Multibyte Support" está como "enable".
Abaixo segue um print do mbstring no phpinfo().
mbstring.jpg

 

Tantas configurações me levaram a dar uma olhada no php.ini, que seguem meus comentários abaixo:

 

Utilizando o manual do PHP (http://us2.php.net/manual/pt_BR/mbstring.configuration.php), achei no php.ini algo interessante, mas não sei se pode ser o causador do problema.

 

Em dado momento do arquivo, temos as configurações do [mbstring], que além de estarem como comentários ( ; ), parecem estar configurados em EUC-JP ao invés de UTF-8.

 

Além do mais, vi nas configurações do php.ini o seguinte:

 

; PHP's default character set is set to empty.
;default_charset = "iso-8859-1"
e
; Default charset for ibase_connect().
;ibase.default_charset =
E agora, tem alguma sugestão? :grin:

Agradeço imensamente por prestar esta grande ajuda a mim e também peço desculpas por estar escrevendo tanto.

Com apenas um comentário seu hinom, já foi possível eu aprender muita coisa.

Grato!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Excelente feedback.

 

Workbench e PHPMyAdmin, ok

 

Collation, charset e DDLs ok

 

MBString OK.

 

 

Vamos aos 10%. rsrsr

 

Eu tinha visto algo estranho no seu código, mesmo antes de terminar de ler o post #1.. Mas preferir conferir primeiro como estava o seu ambiente antes de palpitar.

 

Desative todas essas linhas, pois o seu ambiente parece estar bem configurado para o UTF-8.

Por isso, acredito que esteja provocando uma "dupla codificação". (não sei se existe esse termo).. É basicamente, codificar o UTF-8 para UTF-8.. duas vezes.. rsrsr

 

mysql_set_charset('utf8', $conexao);
ini_set('default_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');

 

 

 

Esse aqui deve ir no bootstrap do aplicativo.

ini_set('default_charset','UTF-8');

Bootstrap é a ignição que prepara o ambiente para execução do app.. num termo mais simples, é onde defini-se as configurações e setagens iniciais.

Pode fazer isso no arquivo index.php, por exemplo, caso todo o roteamento passe por ele.

 

Uma sugestão, no bootstrap, defina o seguinte

 

 

ini_set( 'default_charset', 'UTF-8' );
ini_set( 'mbstring.http_output', 'UTF-8' );
ini_set( 'mbstring.internal_encoding', 'UTF-8' );

 

No momento que lê os dados do banco, remova também essas execuções, caso existam

 

 

mysql_query("SET NAMES 'utf8'");
mysql_query('SET character_set_connection=utf8');
...  e outras relacionadas.. também remover

 

Caso esteja usando uft8_decode() ou utf8_encode() para salvar ou ler dados do banco de dados, remova-os também.

 

Uma vez tendo o ambiente corretamente configurado, não precisa utilizar nenhum desses recursos para esse tipo de operações.

 

E, por fim, não esqueça de definir o charset do header

 

header('Content-Type: text/html; charset=utf-8');

 

 

 

outros assuntos

 

 

 

 

Em dado momento do arquivo, temos as configurações do [mbstring], que além de estarem como comentários ( ; ), parecem estar configurados em EUC-JP ao invés de UTF-8.

EUC-JP é um charset japonês, o qual entrou em desuso há uns 8 anos.. Muitos ainda utilizam por motivos diversos como sistemas legados, custos para modificar ou preguiça mesmo rsrs... Assim como no Brasil muitos ainda "teimam" em usar ISO-8859-1..

A linha comentada deve ser voltada para os japoneses, pois é o público que mais utiliza o mbstring().
Essa library foi escrita, em boa parte, para dar suporte ao idioma japonês e tornou-se util também para boa parte dos idiomas multibyte. Daí o nome da library:

MBString -> Multibyte+String
Há muito mais material, sobre como usar essa library, em idioma japonês e chinês do que em inglês, para ter noção.

 


 

; PHP's default character set is set to empty.
; http://php.net/default-charset
;default_charset = "iso-8859-1"

Esse é o padrão.. conforme o próprio comentário diz.. Então, quando não é definido explicitamente, é assumido a definição de charset do ambiente (Apache, IIS, etc..)

O Apache, normalmente vem com ISO-8859-1 como charset padrão, por isso, é bom definir a setagem no PHP também.

 

Muitas vezes, esse pequeno detalhe causa os conflitos de charset... Por isso, a importância em definir bem o bootstrap.

 

 

Editor de textos.

Uitilzei o EditPad por muitos anos.. Atualmente uso o Notepad++.
Recomendo a migração.

Outro bom também é o Sublime.


 

 

 

Veja também

PHP, HTML, MySQL - Charset Encoding

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boa tarde hinom! Como vai?

 

Obrigado por insistir em ajudar! Suas respostas foram muito esclarecedoras e merecem elogios.

Demorei novamente ( rsrs ) para responder, porque devido eu não ser experiente ou ter conhecimento suficiente, muita coisa fui pesquisar antes de lhe responder.

 

Pra falar a verdade, eu não conhecia o "Bootstrap", e muito menos a função ini_set('default_charset','UTF-8'); que estava em meu código. Simplesmente fui utilizando de sugestões que encontrei em diversos posts e por fim acabei acrescentando no meu script sem ao menos entender corretamente. Agora, após dar uma lida com detalhes em sua resposta e buscar mais algumas informações a respeito deste recurso Bootstrap, notei que na verdade eu não utilizo nada disso em minhas aplicações. Coloquei aquele comando erroneamente em meu script ( hehe ).

 

Só rindo pra não chorar né! kkk

Na realidade, este erro está perseguindo todas as minhas aplicações web, foi onde resolvi criar este banco de dados (conforme post#1) e uma única página de programação (conforme post#3) para facilitar a correção.

Curiosidade: este único arquivo da qual falei, chama-se bd.php

 

Após retirar as linhas que você me pediu, o script ficou conforme segue abaixo:

<?php header("Content-Type: text/html; charset=UTF-8",true); ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="pt-br" xml:lang="pt-br">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Teste</title>
</head>
<body>
<form action="bd.php" method="post">
	Nome: 
	<input type="text" name="nome">
	<input type="submit" value="Enviar">
</form>
<?php
$op = $_GET['op'];
$host = "localhost";
$usuario = "root";
$senha = "admin";
$bd = "banco";

$nome = $_POST['nome'];

$conexao = mysql_connect($host, $usuario, $senha);
mysql_select_db($bd);

	if ($nome) {
	$query = "insert into teste values (NULL, '".$nome."')";
	$resultado = mysql_query($query,$conexao);
	}
	
	$query = "Select * from teste order by idteste desc limit 10";
	
	$resultado = mysql_query($query,$conexao);
	while ($linha = mysql_fetch_array($resultado)){
		echo $linha[0]." - ".$linha[1]."<br>";	
		}
?>
</body>
</html>

Ao retirar as linhas solicitadas fiz 4 testes descritos abaixo:

 

1) utilizei a função mysql_client_encoding(); dentro deste script e desta vez o resultado foi latim1. (antes mostrava utf8).

 

2) fiz um novo teste de envio de um nome acentuado através do formulário e os dados chegaram ao banco de dados da seguinte forma: "Jo├úo". No entanto, ao resgatá-lo via php, o browser exibe corretamente como "João".

 

3) fiz outro teste de envio de um nome acentuado através do formulário, porém desta vez da seguinte forma: $nome = utf8_decode($_POST['nome']); e o resultado gravado no banco de dados foi "Joòo" (exatamente como era no início do post).

 

4) fiz por último um teste com $nome = utf8_encode($_POST['nome']); e o resultado gravado no banco de dados foi "Jo├â┬úo".

 

Resumidamente, tenho 1 banco de dados com as DDLs 'aparentemente corretas', 1 arquivo codificado e com os devidos charsets em utf-8.

 

Teria mais alguma ideia para solucionarmos este caso?

Fico pensando se não é algum erro de configuração, pois fiz a instalação do Apache + MySQL + PHP manualmente. Não sei se seria o caso de eu testar utilizando o XAMPP por exemplo.

 

Inclusive, obrigado por indicar Notepad++, da qual já fiz o download e estou utilizando. E só para constar, o arquivo "bd.php" consta como "codificado em UTF-8 (sem o BOM)" hehe

 

Com relação ao material sobre o EUC-JP, tenho a dizer que tenho a dizer que "vivendo e aprendendo". Dei uma boa lida nele!

 

Obrigado por tudo o que tem feito para ajudar. :joia:

Compartilhar este post


Link para o post
Compartilhar em outros sites


<?php

ini_set( 'default_charset', 'UTF-8' );

ini_set( 'mbstring.http_output', 'UTF-8' );

ini_set( 'mbstring.internal_encoding', 'UTF-8' )

 

header("Content-Type: text/html; charset=UTF-8",true);

?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

...segue o restante do codigo..

Compartilhar este post


Link para o post
Compartilhar em outros sites

hinom, bom dia!

 

rsrs novamente levei algum tempo para responder, por isso peço desculpas.

 

Caro amigo,

 

Fiz as alterações conforme o post #6, mas nada alterou com relação aos resultados. Fiquei indignado e então resolvi desinstalar o apache + php + mysql (algo que já tinha tentado) e instalei como o XAMPP, apenas para ver se o erro iria persistir.

Em seguida fiz o teste e tudo funcionou com excelência!

Então, novamente desinstalei o XAMPP e refiz as instalações anteriores; Contudo desta vez, funcionou corretamente.

 

Logo, podemos notar que o erro era obtido por conta da configuração do servidor local.

Espero que este post possa ajudar outras pessoas com erro similar.

 

Sendo assim, este tópico está resolvido!

 

hinom, as soluções que você me propôs estão em uso neste script final, afim de garantir que tudo continue funcionando corretamente.

 

Agradeço humildemente sua colaboração que foi de grande valia para mim. :joia:

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.