具有UTF-8编码的页面使用UTF-8编码将数据发送到MySQL,但是条目被加扰

时间:2013-07-09 16:04:51

标签: php mysql encoding utf

我意识到有十几个类似的问题,但没有一个解决方案表明在这种情况下有效。

我在页面上有一个PHP变量,初始化为:

$hometeam="Крылья Советов";    //Cyrrilic string

当我在页面上打印出来时,它会正确打印出来。因此,echo $hometeam会显示字符串КрыльяСоветов。

标题中的内容元标记设置如下:

<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">

而且,在页面的最开始,我有以下内容(正如我在搜索中找到的解决方案中所建议的那样):

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

所以这应该都很好。

MySQL表我试图将其保存到,并且相关列中的utf8_bin作为其编码。当我转到phpMyAdmin并手动输入КрыльяСоветов时,它会在现场正确保存。

但是,当我尝试通过页面上的查询保存它时,使用以下基本查询:

mysql_query("insert into tablename (round,hometeam) values ('1','$hometeam') ");

mysql条目如下所示:

c390c5a1c391e282acc391e280b9c390c2bbc391c592c391c28f20c390c2a1c390c2bec390c2b2c390c2b5c391e2809ac390c2bec390c2b2

那么这里发生了什么?如果页面上的一切正常,并且MySQL本身一切正常,问题出在哪里?有什么东西我应该添加到查询本身,以使其保持字符串UTF-8编码?

请注意,我在连接到数据库后(在页面顶部)设置了mysql_set_charset('utf8');

编辑:运行查询SHOW VARIABLES LIKE "%character_set%"会提供以下内容:

Variable_name   Value
character_set_client    utf8
character_set_connection    utf8
character_set_database  latin1
character_set_filesystem    binary
character_set_results   utf8
character_set_server    latin1
character_set_system    utf8
character_sets_dir  /usr/share/mysql/charsets/

似乎这里可能有什么东西,因为该列表中有2个latin1。你觉得怎么样?

另外,当我直接在phpMyAdmin中输入一个西里尔字符串时,它首先显示正常(它在保存后显示正确)。但是重新加载表格,它会像插入的那样显示在HEX中。我为这个问题的错误信息道歉。事实证明,这应该意味着问题在于phpMyAdmin或数据库本身。

编辑#2:这是show create table tablename返回的内容:

CREATE TABLE `tablename` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `round` int(11),  `hometeam` varchar(32) COLLATE utf8_bin NOT NULL,  `competition` varchar(32) CHARACTER SET latin1 NOT NULL DEFAULT 'Russia',  PRIMARY KEY (`id`)) ENGINE=MyISAM AUTO_INCREMENT=119 DEFAULT CHARSET=utf8 COLLATE=utf8_bin

4 个答案:

答案 0 :(得分:2)

你在phpMyAdmin得到这个十六进制字符串吗?我想,当您SELECT插入的值时,例如PHPMySQL控制台客户端,您将获得预期的西里尔字母UTF8字符串。

如果是这样,这是phpMyAdmin的配置问题,请参阅例如在这里:http://theyouri.blogspot.ch/2010/12/phpmyadmin-collated-db-in-utf8bin-shows.html

  

在utf8_bin中的phpMyAdmin整理db显示十六进制数据而不是UTF8文本

     

$ cfg ['DisplayBinaryAsHex'] = false;

此外,请不要使用mysql_query,因为您对SQL注入完全开放。我也不确定你是否真的想使用utf8_bin,参见例如此讨论:utf8_bin vs. utf_unicode_ci或此:UTF-8: General? Bin? Unicode?

编辑有些奇怪的事情发生了。如果将给定的十六进制字符串翻译为UTF8字符,则可以得到:“КрÑ<льÑСовÐμÑ,ов”(参见例如http://software.hixie.ch/utilities/cgi/unicode-decoder/utf8-decoder)。如果你utf8_decode这个,你得到所需的“КрыльяСоветов”。所以,它似乎至少是utf8编码两次(除了它在某处显示为十六进制字符的问题)。

您能提供完整的脚本吗?你在任何地方都utf8_encode了吗?如果您的脚本是这样且只有这个(除了有效的,打开的MySQL连接):

<?php
$hometeam="Крылья Советов";    //Cyrrilic string
// open mysql connection here
mysql_set_charset('utf8');
mysql_query("INSERT INTO tablename (round, hometeam) VALUES ('1', '$hometeam')");
$result = mysql_query("SELECT * FROM tablename WHERE round = '1'");
$row = mysql_fetch_assoc($result);
echo $row['hometeam'];
?>

您调用该页面,结果是什么(在浏览器的页面源中,而不是浏览器中显示的内容)?

此外,请检查如果您将排序规则更改为utf8_unicode_ci会发生什么情况,如此处的另一个答案所示。这至少在显示二进制数据时会覆盖phpMyAdmin问题,并且可能无论如何都是您想要的(因为您可能希望ORDER BY条款按预期执行,请参阅上面链接的SO问题中的讨论。)

EDIT2 也许您还可以提供一些代码段,例如SHOW CREATE TABLE tablenameSHOW VARIABLES LIKE "%character_set%"。可能有帮助。

答案 1 :(得分:1)

1)尝试使用PhpMyAdmin将条目保存到数据库,然后在PhpMyAdmin中查看结果。它看起来不错吗?如果是,则创建并正确设置数据库。

2)尝试使用utf8_general_ci代替。这应该没关系,但试一试。

3)在PHP端调整所有必要的设置 - 按照这篇文章:  http://blog.loftdigital.com/blog/php-utf-8-cheatsheet。特别试试这个技巧:

echo htmlentities($hometeam, ENT_QUOTES, 'UTF-8')

答案 2 :(得分:1)

正如我在评论中看到的那样,你不接缝就能更新你的数据库配置了吗?

我猜您的编码配置错误,因为我在官方文档中看到了MySQL Documentation

我可以为您推荐一个PHP解决方案。由于编码问题很多,您可以在将字符串插入数据库之前对其进行转换。你必须找到一种在PHP和数据库之间交流的通用语言。

我在其他项目中尝试的那个包含使用url_encode($string)url_decode($string)的转换字符串。

答案 3 :(得分:1)

  

另外,当我直接在phpMyAdmin中输入一个西里尔字符串时,它   最初看起来很好(我保存后它显示正确)。但   重新加载表格时,它会像插入的那样显示在HEX中。

这几乎可以肯定你桌子上有问题!运行show create table tablename。我打赌有latin1而不是utf8,因为你将它设置为character_set_database变量的默认值。

要更改此设置,请运行以下命令:

ALTER TABLE tbl_name CONVERT TO CHARACTER SET charset_name;

will convertvarchar字段为utf8。但要小心你已经在表中的记录,因为它们已经格式不正确,如果你将它们转换为UTF8,它们将保持格式错误。也许最好的想法是再次创建数据库,只需在表定义的末尾添加以下命令:

CREATE TABLE `tablename` (
    ....
) ENGINE=<whatever you use> DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci