与UTF-8字符的麻烦; 我看到的不是我所存储的
我试图使用UTF-8并遇到麻烦。
我尝试了很多东西, 这里是我得到的结果:
- ????而不是亚洲人物。 即使是欧洲文本,我也得到- Se?or。
-  奇怪的胡言乱语( Señor?),例如Señor新浪新闻新浪新闻。
- 黑色钻石,如塞尔。
-  最后,我陷入了数据丢失或者至less被截断的情况: SeforSeñ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