php处理emoji表情的问题的方法
给一个标准的解决方案:
-
mysql的版本必须为v5.5.3或更高
-
把数据库表的编码改成
utf8mb4 -- UTF-8 Unicode
-
然后需要存储emoji表情的字段选择
utf8mb4_general_ci
-
数据库连接也需要改为
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 |
+--------------------------+--------------------+
rows in set (0.00 sec)
其他方法解决方案
1、使用utf8mb4字符集
如果你的mysql版本>=5.5.3
,你大可直接将utf8
直接升级为utf8mb4
字符集
这种4字节的utf8编码可完美兼容旧的3字节utf8字符集,并且可以直接存储emoji表情,是最好的解决方案
至于字节增大带来的性能损耗,我看过一些评测,几乎是可以忽略不计的
2、使用base64编码
如果你因为某些原因无法使用utf8mb4的话,你还可以使用base64
来曲线救国
使用例如base64_encode
之类的函数编码过后的emoji可以直接存储在utf8字节集的数据表中,取出时decode一下即可
3、干掉emoji表情
emoji表情是个麻烦的东西,即使你能存储,也不一定能完美显示。在iOS以外的平台上,例如PC或者android。如果你需要显示emoji,就得准备一大堆emoji图片并使用第三方前端类库才行。即便如此,还是可能因为emoji图片不够全而出现无法显示的情况在大多数业务场景下,emoji也不是非要不可的。我们可以适当地考虑干掉它,节约各种成本
经过一番苦苦的google,终于找到靠谱能用的代码:
1 2 3 4 5 6 7 8 9 10 11 12 |
// 过滤掉emoji表情 function filterEmoji( $str ) { $str = preg_replace_callback( '/./u' , function ( array $match ) { return strlen ( $match [0]) >= 4 ? '' : $match [0]; }, $str ); return $str ; } |
以上就是为大家总结的PHP微信开发中涉及到emoji表情的几种处理方法,基本思想就是遍历字符串中的每个字符,如果该字符的长度为4个字节,就将其删除。希望大家喜欢!
这个鬼emoji表情是4个字节,mysql使用的utf8编码,UTF8占3个字节,要存储那个emoji表情需要将mysql编码由UFT8改为UFT8的超集,utf8mb4;
改数据库编码容易引起大面的乱码灾难。所以当遇到emoji字符表情的时候做特殊处理。网上也有很多处理方案,最后找到了一个贴上地址和代码:https://github.com/BriquzStudio/php-emoji ,多谢
class Emoji { /** * Encode emoji in text * @param string $text text to encode */ public static function Encode( $text ) { return self::convertEmoji( $text , "ENCODE" ); } /** * Decode emoji in text * @param string $text text to decode */ public static function Decode( $text ) { return self::convertEmoji( $text , "DECODE" ); } private static function convertEmoji( $text , $op ) { if ( $op == "ENCODE" ){ return preg_replace_callback( '/([0-9|#][\x{20E3}])|[\x{00ae}|\x{00a9}|\x{203C}|\x{2047}|\x{2048}|\x{2049}|\x{3030}|\x{303D}|\x{2139}|\x{2122}|\x{3297}|\x{3299}][\x{FE00}-\x{FEFF}]?|[\x{2190}-\x{21FF}][\x{FE00}-\x{FEFF}]?|[\x{2300}-\x{23FF}][\x{FE00}-\x{FEFF}]?|[\x{2460}-\x{24FF}][\x{FE00}-\x{FEFF}]?|[\x{25A0}-\x{25FF}][\x{FE00}-\x{FEFF}]?|[\x{2600}-\x{27BF}][\x{FE00}-\x{FEFF}]?|[\x{2600}-\x{27BF}][\x{1F000}-\x{1FEFF}]?|[\x{2900}-\x{297F}][\x{FE00}-\x{FEFF}]?|[\x{2B00}-\x{2BF0}][\x{FE00}-\x{FEFF}]?|[\x{1F000}-\x{1F9FF}][\x{FE00}-\x{FEFF}]?|[\x{1F000}-\x{1F9FF}][\x{1F000}-\x{1FEFF}]?/u' , array ( 'self' , "encodeEmoji" ), $text ); } else { return preg_replace_callback( '/(\\\u[0-9a-f]{4})+/' , array ( 'self' , "decodeEmoji" ), $text ); } } private static function encodeEmoji( $match ) { return str_replace ( array ( '[' , ']' , '"' ), '' ,json_encode( $match )); } private static function decodeEmoji( $text ) { if (! $text ) return '' ; $text = $text [0]; $decode = json_decode( $text ,true); if ( $decode ) return $decode ; $text = '["' . $text . '"]' ; $decode = json_decode( $text ); if ( count ( $decode ) == 1){ return $decode [0]; } return $text ; } } |
$nickName = Emoji::Decode($userinfo['nickname']);
$realName = empty($nickName) ? '微信用户:' . time() : $nickName;