优雅实现Mysql数据库存储Emoji表情

in 编程

在做微信公众号开发时碰到一个奇怪的情况:很多用户的昵称都为空,我在公众号后台看了下,他们并不是空昵称,而是用的emoji表情,像这样 ???

我将自己的微信昵称改为「花墨?」,控制台输出的内容为「花墨\ue11a」,如果你手动复制下,粘贴到数据库中的话发现可以放进去,那程序为什么写不进去呢?

原因

多数emoji在存储时需要用到4个字节,而有的emoji是由多个表情组成,更是超过4字节,比如三口之家?‍?‍?则是由???组成。

数据库最常用UTF-8字符集的utf8_general_ci最大支持存储3字节,显然无法存储emoji。

解决方案

知道了原因,可以从代码和数据库两方面入手:

  1. 代码层面:将emoji转码后存储
  2. 数据库层面:修改数据库字符集,使其支持emoji存储

修改代码需要添加一个转义函数,像这个链接,转义函数只转义emoji而不影响其他字符,存入数据库时,就像文章开头所说的「花墨\ue11a」,存入的是\ue11a,那取出来时就得再次转义为emoji表情,这种方法比较麻烦。

刚出说到无法存储emoji是因为UTF8不支持,那就换一个可以支持4字节的字符集utf8mb4。

utf8mb4字符集是从Mysql 5.5.3版本开始支持,因此首先要保证Mysql的版本为5.5+,mb4即 most bytes 4,utf8mb4 是 utf8 的超集并完全兼容utf8,能够用四个字节存储更多的字符。

如果是新项目,新建数据库时可以选择字符集为utf8mb4。

已有的utf8字符集的数据库也可以直接更改为utf8mb4,但因为这一个字段修改全局似乎不是很好的选择,因此可以只修改需要存储emoji的字段为utf8mb4,注意,phpmyadmin并不支持修改字段字符集,需要使用Navicat。

Navicat修改字段字符集为utf8mb4

保存之后直接测试可以存储emoji,但在程序中显示???,别忘了修改程序的数据库连接字符串中的charset=utf8charset=utf8mb4,数据库支持了也得让程序支持。

相对于第一种方式,此方法还是比较简单。

在写本文时,试了下Typecho也是不支持存储emoji,使用上述方法修改后完美解决。

Responses