我意识到有十几个类似的问题,但没有一个解决方案表明在这种情况下有效。
我在页面上有一个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
答案 0 :(得分:2)
你在phpMyAdmin
得到这个十六进制字符串吗?我想,当您SELECT
插入的值时,例如PHP
或MySQL
控制台客户端,您将获得预期的西里尔字母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 tablename
或SHOW 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 convert个varchar
字段为utf8。但要小心你已经在表中的记录,因为它们已经格式不正确,如果你将它们转换为UTF8,它们将保持格式错误。也许最好的想法是再次创建数据库,只需在表定义的末尾添加以下命令:
CREATE TABLE `tablename` (
....
) ENGINE=<whatever you use> DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci