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 中正則表達是才用
八個“ \ ”來匹配;