由于现在数据的版本是5.5.2,但是看网上说要直接存储emoji表情,需要升级到5.5.3然后把字符集设置为utf8mb4,但是升级数据库感觉属于敏感操作。考虑了多久之后直接考虑使用正则来替换,但是emoji表情的unicode码太多了,在网上找了一份代码,还是2年前更新的,想了想还是算了。后来跟老师请教,老师说最简单的办法就是直接找到接受到的文本中的字符串中4个字节的内容,做rawurlencode编码,再入库。输出的时候再替换回来,然后再用rawurldecode转码回unicode到手机再解析为emoji表情。
获取字符串长度mb_strlen,按字符来截取字符串mb_substr(mb_strcut是按字节来截取,有区别)。$strEncode = '';
$length = mb_strlen($str,'utf-8');
for ($i=0; $i
$_tmpStr = mb_substr($str,$i,1,'utf-8');
if(strlen($_tmpStr) >= 4){
$strEncode .= '[[EMOJI:'.rawurlencode($_tmpStr).']]';
}else{
$strEncode .= $_tmpStr;
}
}
echo $strEncode."\n";// 周梦康123~☺[[EMOJI:%F0%9F%98%81]][[EMOJI:%F0%9F%98%84]]
//转码回去
$strDecode = preg_replace_callback("/\[\[EMOJI:(.*?)\]\]/", function($matches){
return rawurldecode($matches[1]);
}, $strEncode);
echo $strDecode."\n";
顺便说下我自己遇到几个坑:
第一个坑:我们线上服务器strlen返回的结果不是字节数,而是字符数。我折腾好半天。最后终于找到了原因:
http://php.net/manual/zh/mbstring.overload.php
再配置文件里设置了mbstring.func_overload=2,而且该配置只能在php.ini里修改,不能通过ini_set来改变。具体参考:http://php.net/manual/en/mbstring.configuration.php; overload(replace) single byte functions by mbstring functions.
; mail(), ereg(), etc are overloaded by mb_send_mail(), mb_ereg(),
; etc. Possible values are 0,1,2,4 or combination of them.
; For example, 7 for overload everything.
; 0: No overload
; 1: Overload mail() function
; 2: Overload str*() functions
; 4: Overload ereg*() functions
; http://php.net/mbstring.func-overload
mbstring.func_overload = 2
这样就导致了str*类的函数都被mb_str*给替换了。具体的参看上面的链接。
第二个坑:PHP 5.3.13中对preg_replace_callback不支持,这个把我坑坏了。直接把匿名函数传入,时而正常时而失效。如果匿名函数还是function ($a) user ($b)的时候则完全不支持。最后我换成单独写一个函数,然后把函数名作为字符串传入,就好了。