与UTF-8字符的麻烦; 我看到的不是我所存储的
我试图使用UTF-8并遇到麻烦。
我尝试了很多东西, 这里是我得到的结果:
????
而不是亚洲人物。 即使是欧洲文本,我也得到Se?or
。- 奇怪的胡言乱语(
Señor
?),例如Señor
新浪新闻
新浪新闻
。 - 黑色钻石,如塞尔。
- 最后,我陷入了数据丢失或者至less被截断的情况:
Se
forSeñor
。 - 即使我的文字看起来不错,也没有正确sorting 。
我究竟做错了什么? 我如何修复代码 ? 我可以恢复数据吗?如果是这样,怎么办?
这个问题困扰着这个网站的参与者,以及其他许多人。
你已经列出了CHARACTER SET
麻烦的五个主要案例。
最佳实践
outlook未来,最好使用CHARACTER SET utf8mb4
和COLLATION utf8mb4_unicode_520_ci
。 (在pipe道中有一个更新的Unicodesorting规则。)
utf8mb4
是utf8
一个超集,它处理4个字节的utf8代码,这是表情符号和一些中文所需要的。
在MySQL之外,“UTF-8”是指所有大小的编码,因此有效地与MySQL的utf8mb4
相同,而不是utf8
。
我将尝试使用这些拼写和大小写来区分内部和外部的MySQL。
你应该做什么的概述
- 让你的编辑器等设置为UTF-8。
- HTML表单应该像
<form accept-charset="UTF-8">
。 - 把你的字节编码为UTF-8。
- build立UTF-8作为客户端使用的编码。
- 将列/表声明为
CHARACTER SET utf8mb4
(使用SHOW CREATE TABLE
检查) - 在HTML开头的
<meta charset=UTF-8>
UTF-8一路通过 (以前叫做“utf8”)
计算机语言的更多细节 (及其后面的部分)
testing数据
用工具或SELECT
查看数据是不可信的。 太多这样的客户端,尤其是浏览器,试图补偿不正确的编码,并显示正确的文本,即使数据库被损坏。 所以,选一个非英文文本的表格和列
SELECT col, HEX(col) FROM tbl WHERE ...
正确存储的UTF-8的hex将是
- 空格(使用任何语言):
20
- 对于英语:
4x
,5x
,6x
或7x
- 在西欧的大部分地区,重音字母应该是
Cxyy
- 西里尔文,希伯来文,波斯文/阿拉伯文:
Dxyy
- 亚洲大部分地区:
Exyyzz
- 表情符号和一些中文:
F0yyzzww
- 更多细节
出现问题的具体原因和解决方法
截断的文本( Se
为Señor
):
- 要存储的字节不被编码为utf8mb4。 解决这个问题。
- 另外,请检查读取期间的连接是否为UTF-8。
有问号的黑色钻石 ( Se or
); 其中一种情况存在:
情况1(原始字节不是 UTF-8):
- 要存储的字节不会被编码为utf8。 解决这个问题。
-
INSERT
和SELECT
的连接(或SET NAMES
)不是utf8 / utf8mb4。 解决这个问题。 - 另外,检查数据库中的列是否是
CHARACTER SET utf8
(或utf8mb4)。
情况2(原始字节是 UTF-8):
-
SELECT
的连接(或SET NAMES
)不是utf8 / utf8mb4。 解决这个问题。 - 另外,检查数据库中的列是否是
CHARACTER SET utf8
(或utf8mb4)。
黑钻只有在浏览器设置为<meta charset=UTF-8>
时才会出现。
问号 (普通的,不是黑色的)( Se?or
Señor
):
- 要存储的字节不被编码为utf8 / utf8mb4。 解决这个问题。
- 数据库中的列不是
CHARACTER SET utf8
(或utf8mb4)。 解决这个问题。 (使用SHOW CREATE TABLE
。) - 另外,请检查读取期间的连接是否为UTF-8。
Señor
( Señor
Señor
):(这个讨论也适用于双重编码 ,这不一定是可见的。)
- 要存储的字节需要使用UTF-8编码。 解决这个问题。
-
INSERTing
和INSERTing
文本时的连接需要指定utf8或utf8mb4。 解决这个问题。 - 该列需要声明
CHARACTER SET utf8
(或utf8mb4)。 解决这个问题。 - HTML应该以
<meta charset=UTF-8>
开头。
如果数据看起来正确,但不能正确sorting,那么要么select了错误的sorting规则,要么没有适合您需要的sorting规则,或者使用双重编码 。
双编码可以通过执行上述SELECT .. HEX ..
来确认。
é should come back C3A9, but instead shows C383C2A9 The Emoji 👽 should come back F09F91BD, but comes back C3B0C5B8E28098C2BD
也就是说,这个hex大约是它的两倍。 这是由latin1(或其他)转换为utf8引起的,然后将这些字节视为latin1并重复转换。 sorting(和比较)不能正常工作,因为它是,例如,如果string是Señor
。
在可能的情况下修复数据
对于截断和问号 ,数据丢失。
对于Mojibake / 双重编码 ,…
对于黑钻石 ,…
(我必须在另一个问题/答案中继续。)
有趣的你如何回答你自己的问题:)
1 – 将您的代码IDE语言设置为UTF8
2 – 添加到您收集数据表单的网页标题。
3 – 检查你的MySQL表的定义如下所示:
CREATE TABLE your_table ( ... ) ENGINE=InnoDB DEFAULT CHARSET=utf8
4 – 如果您正在使用PDO,请确保
$options = array(PDO::MYSQL_ATTR_INIT_COMMAND=>'SET NAMES utf8'); $dbL = new PDO($pdo, $user, $pass, $options);
如果你已经有了一个大型的数据库,你可以尝试使用正确的字符集导出SIDU,然后用UTF8导入。 祝你好运
根据服务器的设置,您必须相应地更改编码。 utf8从你说的应该最好的工作,但是如果你得到奇怪的字符,它可能会帮助,如果你改变网页编码为Ansi。 这帮助我,当我设置一个PHP的MYSQLI这可能会帮助你了解更多https://superuser.com/questions/762473/ansi-to-utf-8-in-notepad