微信昵称包含emoji表情,保存异常

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 中正则表达是才用

八个“ \ ”来匹配;

 

转载于:https://www.cnblogs.com/oneyear/p/8469872.html

你可能感兴趣的:(数据库,json)