概述:
最近一個項目中調用同事封裝的一個微信獲取信息接口並處理字段存入數據庫處理的功能接口,功能測試階段發現關注公眾號信息並沒有成功返回,而且情況是一些賬號是正常的,一些人卻是有問題的,針對有問題的用戶查看日志發現微信官方返回的關注狀態與同事接口返回的內容不符合,也就是說沒有正常更新到。日志記錄相關SQL,插入數據庫才發現是微信的emjoy符號導致出現問題。
mysql報錯內容:
根據上圖看見,是mysql對特殊號的報錯。
方案概況:
針對符號的報錯,搜索了有沒有解決方案,並且發現了有兩個解決方法。
修改mysql的編碼。
對字符過濾后再插入數據庫
具體方案:
1、修改mysql的編碼:
Mysql的utf8編碼最多3個字節,而Emoji表情或者某些特殊字符是4個字節。因此我們需要修改編碼能接受4個字節的,例如utf8mb4。
在mysql的安裝目錄下找到my.ini,作如下修改:[mysqld] character-set-server=utf8mb4 [mysql] default-character-set=utf8mb4
重啟mysql服務
修改表 ALTER TABLE 表名 CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
2、特殊字符過濾:
其實很多時候數據庫中儲存的微信昵稱完整性不是特別重要,例如:“小蕾??”’ 保存為“小蕾” ,可以考慮直接過濾特殊字符,這樣的優點是不用擔心修改mysql編碼過程中造成其他錯誤。
//微信特殊字符過濾
private function wx_name_filter($str) {
$name = $str;
$name = preg_replace('/\xEE[\x80-\xBF][\x80-\xBF]|\xEF[\x81-\x83][\x80-\xBF]/', '', $name);
$name = preg_replace('/xE0[x80-x9F][x80-xBF]‘.‘|xED[xA0-xBF][x80-xBF]/S','?', $name);
$return = json_decode(preg_replace("#(\\\ud[0-9a-f]{3})#ie","",json_encode($name)));
if(!$return){
return $this->jsonName($return);
}
return $str;
}
總結:
個人業務原因采取了過濾字符方案,並且生效了,其實兩種方法都挺方便易懂的,主要是看自己需求,如果項目中太多需要修改的地方,那么修改mysql編碼方案也不失為一種好方法,當然要注意小心操作。
PS:記錄一下更改數據庫格式的代碼
show full columns from blog_member;
-- show variables like '%char%';
-- ALTER TABLE blog_employee CHANGE nickname nickname VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- ALTER TABLE blog_employee CHANGE name name VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE blog_member CHANGE nickname nickname VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- ALTER TABLE blog_member CHANGE nickname nickname VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- ALTER TABLE blog_member nickname CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- set global innodb_file_format = BARRACUDA;
-- set global innodb_large_prefix = ON;
-- show variables like 'character%';
-- show variables like 'collation_%';
-- show variables like 'innodb_large_prefix';
-- show variables like 'innodb_file_format';
最后修改mysql配置文件並且重啟才真正生效
my.cnf一般在etc/mysql/my.cnf位置。找到后請在以下三部分里添加如下內容:
[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'
求一鍵三連:點贊、轉發、在看