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 中正则表达是才用
八个 \ 来匹配;
来源: http://www.bubuko.com/infodetail-2506889.html