存储emoji表情或特殊字符报错(Incorrect string value: '\xF0\x9F\x98\x82\xF0\x9F...')
今天发生一件有趣的事情。
我在一篇文章中使用了emoji表情
,前面很顺利,不管是WordPress还是其他博客园啥的,都是正常发送。
但是,我在Typecho系统中发布文章时....
我当时一脸懵逼,啥情况,数据库坏了?
我重启服务器,发现没用,于是准备直接使用Navicat
工具直接写入数据库。
巧了,还是报错,不管可算知道问题了。
浏览器搜索一番后,发现,是表情的问题。
如何解决?
于是既然是错误,那我就解决一下吧。
首先,我们要知道,utf8是Typecho系统写入数据库是的默认编码,也是安装MySQL是的默认编码。
Typecho 默认是不支持 Emoji 表情的,当你评论中有 Emoji 的话,就会报这个错误。这个是因为编码的问题造成的。Mysql 默认使用的是 utf8 字符集,utf8 字符集的编码范围 u0000-uFFFF,而 Emoji 是在 Unicode 位于 u1F601-u1F64F 区段的字符。所以评论中带有 Emoji 表情才会报错。
-
修改Typecho配置文件
Typecho修改网站的配置文件,打开网站根目录,找到
config.inc.php
文件,把charset
的值改为urf8mb4
。如果是Java,可以修改数据库连接字符串的编码。其他语言也类似。
-
修改MySQL全局默认编码
首先,找到
my.cnf
文件,Window是my.ini
文件。宝塔面板直接找。
[client] default-character-set = utf8mb4 [mysql] default-character-set = utf8mb4 [mysqld] character-set-client-handshake = FALSE character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci init_connect='SET NAMES utf8mb4'
找到之后直接将上面这串代码粘贴到文件的空位置,一般就最下面就可以。
这样之后,重启MySQL服务。
重启之后效果我们可以使用SQL语句看看。
上面部分是没改之前的,下面是改完后。
这样就可以了。
- Typecho玩家请注意!
alter table typecho_comments convert to character set utf8mb4 collate utf8mb4_general_ci;
alter table typecho_contents convert to character set utf8mb4 collate utf8mb4_general_ci;
alter table typecho_fields convert to character set utf8mb4 collate utf8mb4_general_ci;
alter table typecho_metas convert to character set utf8mb4 collate utf8mb4_general_ci;
alter table typecho_options convert to character set utf8mb4 collate utf8mb4_general_ci;
alter table typecho_relationships convert to character set utf8mb4 collate utf8mb4_general_ci;
alter table typecho_users convert to character set utf8mb4 collate utf8mb4_general_ci;
请运行这一段SQL语句,至于怎么运行这就不说了,太基础。
这样,就可以正常发布带有表情的文章了。
延伸知识
1、MySQL在5.5.3之后增加了这个utf8mb4的编码,所以最低mysql版本支持版本为5.5.3+,若不是,请升级到较新版本;
2、mb4就是most bytes 4的意思,可以用来兼容四字节的unicode,存储与获取数据的时候,不用再考虑表情字符的编码与解码问题。如果你要存互联网emoji表情,就需要utf8mb4,而不是utf-8;
3、utf8mb4是utf8的超集,除了将编码改为utf8mb4外不需要做其他转换;
4、MySQL数据库的 “utf8”并不是真正概念里的 UTF-8,MySQL中的“utf8”编码只支持最大3字节每字符。真正的大家正在使用的UTF-8编码是应该能支持4字节每个字符,MySQL的开发者没有修复这个bug。他们在2010年增加了一个变通的方法:一个新的字符集“utf8mb4”,他们并没有对外公布(可能因为这个bug有点尴尬)。现在很多指南推荐用户使用“utf8”其实都错了;
5、建议MySQL和MariaDB用户使用“utf8mb4”而不是“utf8”,毕竟现在是不管使用 Anroidz设备,还是 iOS 设备,如果插入包含有 emoji 表情符号的记录时就报错,还是很尴尬的;
6、最重要一点,对数据库操作前,记得备份数据。
为什么要修改编码才行?
为什么要把数据库的字符集设置成utf8mb4呢?以前一直用的都是utf8啊?
utf8适用于不使用移动设备的互联网交互,utf8mb4适用于当前的移动设备互联网开发,因为移动设备中常常会有表情符号(emoji)的存储,它占用4个字节的存储空间,而utf8是3个字节,这样,用3个字节去存储4个字节的东西,很明显是存不下的,会报错,所以要用utf8mb4,并且utf8mb4是兼容utf8的,那么,就没有理由不用utf8mb4字符集了。