[FUG-BR] Mysql não aceita acentos.

Rafael Fernandes ragatol em netsite.com.br
Domingo Fevereiro 25 22:54:27 BRT 2007


Não precisa de muito para fazer o teste não. Apenas rode o código a seguir:

--------- teste.php
<!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">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
	<title>Character-set de conexão com o mysql</title>
</head>
<body>
<?php

// Ok, vamos brincar com um texto antes usando o que temos de charset
// de conexão padrão no servidor (deveria ser latin1, se não foi ajustado
// outra coisa ao compilar a biblioteca)
mysql_connect( "localhost", "root", "leleafar" );
// Vamos ver qual é o charset padrão usado na conexão.
$r = mysql_fetch_row(mysql_query("select charset('abc');"));
echo "<p>Charset Padrão desta conexão: $r[0]</p>\n";
// Bom, vamos fazer uma tabelinha com o charset latin1 no banco test
// que o mysql cria por padrão
if (mysql_query("create table if not exists `test`.`chartest` (texto TEXT)  
character set latin1;"))
	echo "<p>Tabela criada!</p>";
else {
	echo "<p>Erro ao criar a tabela.</p>";
	exit(0);
}
// Beleza, vamos fazer um teste para guardar o texto com acentuação
$texto = "áéíóçãõà";
echo "<p>Texto para testes: $texto (deve estar aparecendo corretamente no  
navegador!)</p>\n";
mysql_query("insert into `test`.`chartest` set texto = '$texto';");
// Vamos ver o que ele guardou?
$r = mysql_fetch_row(mysql_query("select texto from `test`.`chartest`;"));
if ($r[0] == $texto)
	echo "<p>O texto permanece igual!</p>";
else
	// isto não deveria acontecer se seu módulo mysql estiver em latin1
	echo "<p>Opa, o texto foi modificado! Texto retornado: $r[0]</p>\n";
mysql_close();
// Ok, o legal é que o código acima tenha como resultado o texto  
permanecer igual. Isto quer dizer que nossa conexão é latin1,
// Mas, qual seria o resultado se nossa conexão fosse, por padrão, em  
utf-8? Vamos descobrir.
mysql_connect( "localhost", "root", "leleafar" );
// Vamos mudar o charset da conexão apenas (deve ser a primeira coisa a  
ser feita, pelo o que está na documentação);
// Leia sobre isto onde indiquei anteriormente:  
http://dev.mysql.com/doc/refman/5.0/en/charset-connection.html
mysql_query("set NAMES utf8;");
// Vamos fazer nosso teste de descobrir qual o charset padrão para  
verificar se deu certo a query anterior.
$r = mysql_fetch_row(mysql_query("select charset('abc');"));
// Deve mostrar utf8 como resultado.
echo "<p>Charset Padrão desta conexão: $r[0]</p>\n";
// Vamos ver o que ele retorna pra gente agora?
$r = mysql_fetch_row(mysql_query("select texto from `test`.`chartest`;"));
if ($r[0] == $texto)
	echo "<p>O texto permanece igual!</p>";
else
	echo "<p>Opa, o texto foi modificado! Texto retornado: $r[0]</p>\n";
// Se o charset padrão desta conexão for utf-8, você já percebeu que o  
texto foi "alterado"... mas nem tanto!
// Na verdade, seu texto foi retornado em utf-8, MESMO COM A TABELA  
MARCADA COMO LATIN1
// Vamos conferir?
if ($texto == utf8_decode($r[0]))
	echo "<p>É o mesmo texto realmente, só que foi retornado em UTF-8!</p>\n";
/* Entendeu o problema? O problema não é na tabela, nem no locale, e sim  
no charset usado pelo módulo php, que tem
o charset padrão dependente de como foi compilada antes a biblioteca do  
mysql, pois não conheço arquivo de
configuração para esta biblioteca. */
// Vamos acabar com nossa tabela de testes
mysql_query("drop table `test`.`chartest`;");
mysql_close();	
?>
</body>
--------- fim

Como te disse, no meu caso, é complicado ajustar os scripts para usar  
uft8_decode ou a query de mudar o charset da conexão num site de mais de 8  
anos (onde trabalhei apenas nos 2 últimos), que passou por várias pessoas  
diferentes, e com vários setores desenvolvidos por pessoas diferentes,  
quase sempre de maneira totalmente desorganizada.

A solução simples e eficiente no meu caso foi recompilar a biblioteca e o  
módulo para usarem latin1 como padrão de conexão, pois estavam em utf-8.

Acho que agora estará satisfeito, vendo o resultado disto com os próprios  
olhos.

Até,

Rafael.

On Sun, 25 Feb 2007 13:32:16 -0300, Eder <ederbsd em gmail.com> wrote:

> Em momento algum disse que não acreditava em suas explicações,
> tanto que não contestei o resto do email, porque o que falou está  
> correto.
>
> Simplesmente procurei, e não encontrei nada que o justificase, inclusive
> compilei o PHP aqui na minha máquina, via ports, e modulo php para MySQL,
> mais não tive o problema, agora se eu alterar os caracteres no database  
> do MySQL
> para outro tipo, os acentos não entram corretos, ou entram de forma  
> errônea.
> Em Latin1 funciona corretamente.
>
>>> espero que não venha a ter o problema que tivemos.
>
> R = Eu espero ter sim, assim posso testar realmente se o que falou,
> se contesta, como posso simular o erro?
>
> Att Eder.
>
>
> On 2/25/07, Rafael Fernandes <ragatol em netsite.com.br> wrote:
>> Como te disse, no caso do que aconteceu comigo e com nosso colega de
>> lista, mudar o charset da tabela não resolveria.
>> Eu tentei explicar da melhor maneira possível mas se ainda assim não
>> acredita no que estou explicando, espero que não venha a ter o problema
>> que tivemos.
>>
>> Até,
>>
>> Rafael.
>>
>> On Sun, 25 Feb 2007 12:37:17 -0300, Eder <ederbsd em gmail.com> wrote:
>>
>> >>> No meu caso, mudar estas configurações no servidor mysql não  
>> resolveu.
>> >>> O
>> >>> servidor mudou sim de charset usado nas conexões, mas o módulo do  
>> php
>> >>> não.
>> >>> E o módulo do php depende da biblioteca do mysql, que por sua vez  
>> tem
>> >>> em
>> >>> seu código pre-definido quando compilado qual o charset padrão. Eu  
>> não
>> >>> sei
>> >>> como mudar o padrão da biblioteca sem recompilar, se você souber me
>> >>> desculpe mas é que não encontrei outro meio mesmo.
>> >
>> > R = Como eu disse não entendo de PHP, mais creio que não é necessário
>> > recompilar nada, como sugere eu recompilar um C/C++?
>> >
>> > Basta alterar essas configurações no banco.
>> >
>> > ALTER DATABASE name_database DEFAULT CHARACTER SET latin1 COLLATE
>> > latin1_swedish_ci;
>> >
>> > Att, Eder.
>> >
>> >
>> > On 2/25/07, Rafael Fernandes <ragatol em netsite.com.br> wrote:
>> >> Oi de novo! :D
>> >>
>> >> Quando um cliente de mysql conecta ao banco, via o cliente padrão  
>> mysql
>> >> ou
>> >> biblioteca, existe a negociação de um charset para a interpretação do
>> >> texto enviado entre ambos, independente dos dados do banco ou do  
>> texto
>> >> da
>> >> linguagem (em c++ ou no caso o php). Quer dizer, temos 1 "camada" de
>> >> conversão de charsets internamente no servidor mysql quando ele
>> >> lê/escreve
>> >> nas tabelas, 1 "camada" de conversão de charsets quando os dados
>> >> trafegam
>> >> entre o servidor e o cliente/biblioteca mysql (esta camada tanto não
>> >> segue
>> >> locale, apenas uma negociação entre o servidor e o  
>> cliente/biblioteca,
>> >> quanto é a causa do problema inicial), e + 1 "camada" quando o texto  
>> é
>> >> trabalhado no programa do usuário.
>> >> Por exemplo, uma string no php usaria a codificação iso por padrão.  
>> Mas,
>> >> se você usa um módulo de php que conecta ao servidor em utf-8, você  
>> deve
>> >> codificar esta string em uft-8 antes de enviar por um mysql_query.  
>> Como
>> >> a
>> >> diferença mesmo entre as 2 codificações são os acentos e outros
>> >> caracteres
>> >> acima de 127 (o que não afeta a sintaxe do mysql, e claro não estou
>> >> falando de codificações com 2 bytes ou mais como a unicode), ocorre o
>> >> problema que foi colocado, a "não aceitação" de acentos, com o mysql
>> >> recebendo os códigos de caractere em codificação diferente da  
>> informada
>> >> pela conexão do cliente (no caso, o próprio módulo do php).
>> >>
>> >> Ficar tomando cuidado com quando usar as funções utf8_encode e
>> >> utf8_decode
>> >> no PHP levaria às "aleatoriedades" que mencionei, principalmente  
>> quando
>> >> você migra código e dados desenvolvidos com a espectativa de que  
>> estas
>> >> funções não seriam necessárias. Usar o setlocale no php também não
>> >> resolveria porque isto modificaria apenas o processamento interno do  
>> php
>> >> em relação às strings (no caso do seu exemplo, mudaria a "colagem":  
>> qual
>> >> caractere com acentuação é ligado com qual caractere "puro". O "case
>> >> insensitive" é um tipo de colagem: cola minúsculas com maiúsculas,  
>> não
>> >> diferenciando elas), horário, moeda e outras coisas, e não quando ele
>> >> envia texto pelo módulo. Eu mesmo tive que arrumar muitas páginas php
>> >> com
>> >> as funções utf8 enquanto tentava descobrir esse detalhe da  
>> codificação
>> >> da
>> >> conexão.
>> >>
>> >> No meu caso, mudar estas configurações no servidor mysql não  
>> resolveu. O
>> >> servidor mudou sim de charset usado nas conexões, mas o módulo do php
>> >> não.
>> >> E o módulo do php depende da biblioteca do mysql, que por sua vez  
>> tem em
>> >> seu código pre-definido quando compilado qual o charset padrão. Eu  
>> não
>> >> sei
>> >> como mudar o padrão da biblioteca sem recompilar, se você souber me
>> >> desculpe mas é que não encontrei outro meio mesmo.
>> >>
>> >> O que tinha sugerido para solução é justamente isto: recompilando o
>> >> mysql-server, seria recompilada também a biblioteca, usando o mesmo
>> >> charset para conexões por padrão, se o módulo do php dele fosse  
>> linkado
>> >> dinamicamente isto já resolveria também o problema dentro do php (se  
>> o
>> >> módulo for linkado estaticamente com a biblioteca mysql, seria
>> >> necessário
>> >> recompilá-lo também!), então ele não seria obrigado a usar as funções
>> >> utf8
>> >> sempre que quisesse fazer uma query ao banco. Se ele não tiver um
>> >> computador que seja antigo a ponto de isto ser proibitivo, é mais
>> >> simples
>> >> fazer o que sugeri ao invéz de tudo o que envolveria se fosse  
>> resolver
>> >> de
>> >> outro modo. Claro que eu estava me baseando no meu caso, num site  
>> onde
>> >> existem vários sub-sites, cada um feito por um tipo de pessoa, com  
>> nível
>> >> de conhecimento também variável, pior seria se eu me preocupasse em
>> >> ajustar isto pelo php. E acreditei que isto também serviria para ele,
>> >> até
>> >> porque seria uma chamada de função a menos para cada query.
>> >>
>> >> O que eu tinha entendido, pela sua primeira mensagem, era que você
>> >> esperava que o problema fosse solucionado com a mudança do charset da
>> >> tabela, o que ele já havia tentado. Por isto, pensei que você não
>> >> estivesse muito a par de outras causas para o problema inicial, assim
>> >> como
>> >> a pessoa que o colocou em questão. Não foi minha intenção caçoar de
>> >> você,
>> >> apenas esclarecer o porquê da minha sugestão. ;)
>> >>
>> >> Até,
>> >>
>> >> Rafael.
>> >>
>> >>
>> >> > Oi,
>> >> >
>> >> >>> O problema, Eder, é que pode haver uma diferença de charset  
>> usado na
>> >> >>> conexão entre o cliente e o servidor mysql.
>> >> >
>> >> > R = Obviamente que pode haver, por isso existem os locales. Tanto  
>> no
>> >> > banco quanto na linguagem, não entendo muito de PHP, mais em C, C++
>> >> > basta passar o locale.
>> >> >
>> >> >>> E o problema continua mesmo depois de mudado o charset
>> >> >>> de uma tabela que era utf-8 para latin1. Como disse, não é um
>> >> problema
>> >> >>> no
>> >> >>> chaset usado pelo servidor, mas sim pela conexão entre o  
>> servidor e
>> >> um
>> >> >>> cliente mysql, pois nessa ele tenta fazer uma conversão de  
>> charsets.
>> >> >>> Leia
>> >> >>> sobre isto aqui:
>> >> >
>> >> > R = Concordo, então no PHP set o locale,
>> >> >
>> >> > setlocale(LC_COLLATE,  "pt_BR.ISO8859-1");
>> >> >
>> >> >>> A única coisa que fez os resultados de queries serem consistentes
>> >> foi
>> >> >>> certificando que ambos os binários (cliente e servidor) usavam o
>> >> mesmo
>> >> >>> charset padrão para conexões. E infelizmente isto fica compilado
>> >> com os
>> >> >>> binários, não fica em um arquivo de configuração. Senão não
>> >> >>> precisaríamos
>> >> >>> de ajustar esta opção ao compilar o mysql, certo?
>> >> >
>> >> > R = Errado, não é necessário recompilar o MySQL para configurar  
>> isso,
>> >> se
>> >> > ele por
>> >> > padrão já é compilado com suporte aos characters.
>> >> >
>> >> > mysql> SHOW VARIABLES LIKE 'coll%';
>> >> > mysql> SHOW VARIABLES LIKE 'character%';
>> >> >
>> >> > No arquivo de configuração do mysql no /etc/my.cnf basta setar o
>> >> locale.
>> >> >
>> >> > [mysqld]
>> >> > character_sets_dir=/usr/local/share/mysql/charsets/
>> >> > default-character-set=utf8
>> >> > default-collation=utf8_general_ci
>> >> >
>> >> > [client]
>> >> > default-character-set=utf8
>> >> >
>> >> >>> Então, me desculpe, mas listar os charsets disponíveis para as
>> >> tabelas
>> >> >>> não
>> >> >>> resolveria o problema do nosso amigo da lista.
>> >> >
>> >> > R = Realmente digitar o comando não resolveria em nada.
>> >> >
>> >> > Att Eder,
>> >> >
>> >> >
>> >> > On 2/24/07, Rafael Fernandes <ragatol em netsite.com.br> wrote:
>> >> >> O problema, Eder, é que pode haver uma diferença de charset usado  
>> na
>> >> >> conexão entre o cliente e o servidor mysql.
>> >> >>
>> >> >> Normalmente, no módulo php, isto acarreta em aleatoriamente você
>> >> receber
>> >> >> os dados em latin1 e utf-8, mesmo quando uma tabela está com a  
>> opção
>> >> de
>> >> >> charset em latin1. E o problema continua mesmo depois de mudado o
>> >> >> charset
>> >> >> de uma tabela que era utf-8 para latin1. Como disse, não é um
>> >> problema
>> >> >> no
>> >> >> chaset usado pelo servidor, mas sim pela conexão entre o servidor  
>> e
>> >> um
>> >> >> cliente mysql, pois nessa ele tenta fazer uma conversão de  
>> charsets.
>> >> >> Leia
>> >> >> sobre isto aqui:
>> >> >> http://dev.mysql.com/doc/refman/5.0/en/charset-connection.html
>> >> >>
>> >> >> Este problema aconteceu comigo quando migrei um banco de dados de  
>> um
>> >> >> servidor para outro. Como o charset da tabela não foi alterado,  
>> não
>> >> era
>> >> >> para ocorrer este tipo de problema. E a única diferença entre um
>> >> >> servidor
>> >> >> e outro era que o charset padrão usado nas conexões era diferente
>> >> >> (latin1
>> >> >> no antigo, utf-8 no novo).
>> >> >>
>> >> >> A única coisa que fez os resultados de queries serem consistentes  
>> foi
>> >> >> certificando que ambos os binários (cliente e servidor) usavam o
>> >> mesmo
>> >> >> charset padrão para conexões. E infelizmente isto fica compilado  
>> com
>> >> os
>> >> >> binários, não fica em um arquivo de configuração. Senão não
>> >> >> precisaríamos
>> >> >> de ajustar esta opção ao compilar o mysql, certo?
>> >> >>
>> >> >> Então, me desculpe, mas listar os charsets disponíveis para as
>> >> tabelas
>> >> >> não
>> >> >> resolveria o problema do nosso amigo da lista.
>> >> >>
>> >> >> Até,
>> >> >>
>> >> >> Rafael.
>> >> >>
>> >> >> On Sat, 24 Feb 2007 15:20:04 -0200, Eder <ederbsd em gmail.com>  
>> wrote:
>> >> >>
>> >> >> > Olá,
>> >> >> >
>> >> >> > Basta alterar o character sets.
>> >> >> >
>> >> >> > mysql>  SHOW CHARACTER SET;
>> >> >> >
>> >> >> > http://dev.mysql.com/doc/refman/5.0/en/charset-mysql.html
>> >> >> >
>> >> >> > Att, eder.
>> >> >> >
>> >> >> > On 2/23/07, Rafael Fernandes <ragatol em netsite.com.br> wrote:
>> >> >> >> É amigo eu passei por isto e normalmente o mysql fica com o
>> >> charset
>> >> >> >> compilado tanto no servidor quanto no cliente (ou bibliotecas
>> >> usadas
>> >> >> por
>> >> >> >> outros programas, no caso o php).
>> >> >> >> O que solucionou meu problema 100% foi recompilar o  
>> mysql-server
>> >> (se
>> >> >> não
>> >> >> >> me engano, isto já recompila a biblioteca mysql-server, mas
>> >> confira).
>> >> >> >> Recompile também o módulo mysql do php se ele foi linkado
>> >> >> estaticamente
>> >> >> >> com a biblioteca mysql.
>> >> >> >>
>> >> >> >> Lembre-se sempre que usamos latin1/iso-8859-1 (são a mesma  
>> coisa)
>> >> e
>> >> >> irá
>> >> >> >> evitar muita dor de cabeça.
>> >> >> >>
>> >> >> >> Até,
>> >> >> >>
>> >> >> >> Rafael.
>> >> >> >>
>> >> >> >> On Fri, 23 Feb 2007 11:56:32 -0200, Rafael Stockler
>> >> >> >> <rafael.stockler em gmail.com> wrote:
>> >> >> >>
>> >> >> >> > Bom dia a todos,
>> >> >> >> >
>> >> >> >> > Estou com o seguinte problema.
>> >> >> >> >
>> >> >> >> > Tenho aqui instalado o Apache 2, php 5 e mysql 5.
>> >> >> >> >
>> >> >> >> > O problema que estou enfrentando é o fato de o mysql não  
>> estar
>> >> >> >> > cadastrando palavras com acentos. Verifiquei se o php estava
>> >> >> mostrando
>> >> >> >> > certo e pelo q vi sim.
>> >> >> >> >
>> >> >> >> > O charset no mysql eh o utf8-general. Jah tentei colocar o
>> >> latin 1
>> >> >> e
>> >> >> >> > outras e nada.
>> >> >> >> >
>> >> >> >> > Alguem já passou por isso ou saberia o q pode ser isso?
>> >> >> >> >
>> >> >> >> > Vlw.
>> >> >> >> > -------------------------
>> >> >> >> > Histórico: http://www.fug.com.br/historico/html/freebsd/
>> >> >> >> > Sair da lista:  
>> https://www.fug.com.br/mailman/listinfo/freebsd
>> >> >> >>
>> >> >> >>
>> >> >> >> -------------------------
>> >> >> >> Histórico: http://www.fug.com.br/historico/html/freebsd/
>> >> >> >> Sair da lista: https://www.fug.com.br/mailman/listinfo/freebsd
>> >> >> >>
>> >> >> >
>> >> >> >
>> >> >>
>> >> >>
>> >> >> -------------------------
>> >> >> Histórico: http://www.fug.com.br/historico/html/freebsd/
>> >> >> Sair da lista: https://www.fug.com.br/mailman/listinfo/freebsd
>> >> >>
>> >> >
>> >> >
>> >>
>> >>
>> >> -------------------------
>> >> Histórico: http://www.fug.com.br/historico/html/freebsd/
>> >> Sair da lista: https://www.fug.com.br/mailman/listinfo/freebsd
>> >>
>> >
>> >
>>
>>
>> -------------------------
>> Histórico: http://www.fug.com.br/historico/html/freebsd/
>> Sair da lista: https://www.fug.com.br/mailman/listinfo/freebsd
>>
>
>




Mais detalhes sobre a lista de discussão freebsd