MySQL要存储emoji表情,由于emoji表情的unicode编码占用4个字节,而Mysql的utf8编码最多只能存储3个字节,
所以保存到数据库时会产生异常,一般两种解决方法,
方法一
修改数据库的字符集为utf8mb4,MySQL支持 emoji 表情的最低版本为5.5.3,否则不支持字符集utf8mb4。
# 修改数据库: ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci; # 修改表: ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; # 修改表字段: ALTER TABLE table_name CHANGE column_name column_name VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
修改mysql的配置文件,一般在/etc/my.cnf,最重要的修改是 [mysqld] 的配置添加
[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> SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%'; +--------------------------+--------------------+ | Variable_name | Value | +--------------------------+--------------------+ | character_set_client | utf8mb4 | | character_set_connection | utf8mb4 | | character_set_database | utf8mb4 | | character_set_filesystem | binary | | character_set_results | utf8mb4 | | character_set_server | utf8mb4 | | character_set_system | utf8 | | collation_connection | utf8mb4_unicode_ci | | collation_database | utf8mb4_unicode_ci | | collation_server | utf8mb4_unicode_ci | +--------------------------+--------------------+
mysql> SHOW FULL FIELDS FROM tbl_user;
注意程序连接数据库时,是否支持该字符集
方法二
如果有些情况修改数据库配置的方式不可执行,则只能从程序段动手,原则就是转码保存再转码显示
/** 把用户输入的文本转义(主要针对特殊符号和emoji表情) */ public function userTextEncode($str){ if(!is_string($str))return $str; if(!$str || $str=='undefined')return ''; $text = json_encode($str); //暴露出unicode $text = preg_replace_callback("/(\\\u[ed][0-9a-f]{3})/i",function($str){ return addslashes($str[0]); },$text); //将emoji的unicode留下,其他不动,这里的正则比原答案增加了d,因为我发现我很多emoji实际上是\ud开头的,反而暂时没发现有\ue开头。 return json_decode($text); } /** 解码上面的转义 */ public function userTextDecode($str){ $text = json_encode($str); //暴露出unicode $text = preg_replace_callback('/\\\\\\\\/i',function($str){ return '\\'; },$text); //将两条斜杠变成一条,其他不动 return json_decode($text); }
即将emoji表情的unicode编码保存到数据库中,待取出时候再做转义回,使用上面的方法需要注意
1)中文字符串经过json_encode后生成的json字符串,是用''括起来的,例如'"\ud83c\udf89 \ud83d\udcb0"',尤其
是做测试用作参数时候,如果没有单引号直接json_decode是返回null的;
2)json_encode的字符串中包含转义字符“ \ ”时,编码后会生成两个“ \ ”,所以方法 userTextDecode 中正则表达是才用
八个“ \ ”来匹配;