[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