解决微信emjoy特殊符号插入数据库出错
概述:
最近一个项目中调用同事封装的一个微信获取信息接口并处理字段存入数据库处理的功能接口,功能测试阶段发现关注公众号信息并没有成功返回,而且情况是一些账号是正常的,一些人却是有问题的,针对有问题的用户查看日志发现微信官方返回的关注状态与同事接口返回的内容不符合,也就是说没有正常更新到。日志记录相关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'
求一键三连:点赞、转发、在看
赞赏码
非学,无以致疑;非问,无以广识