Lei Zhang

时光已逝永不回,
往事只能回味。
... ...
春风又吹红了花蕊,
你已经也添了新岁。

▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ 96%



处理微信公众号粉丝中包含Emoji表情的昵称

2017-11-29 » PHP / 微信开发

在 MySQL 5.5 之前,MySQL 只支持 utf8 字符集,这种字符集只支持最多3个字节的存储,而 emoji 却是4字节的字符,因此导致存储出现乱码失败等情况。如果要让你的数据库支持 emoji 存储,MySQL 必须升级至 5.5 及以上。

在 MySQL 5.5 及以上版本,MySQL 支持 utf8mb4,这种字符集是 utf8 的超集,比 utf8 能存储更多位的字节,并完全兼容 utf8。

拿微信粉丝的昵称(nickname)字段举例,可以单独将其字符集设置成 utf8mb4,就可正确存储带有 emoji 的字符,或者你也可以将整张表、数据库的字符集设置成 uf8mb4。当你决定将整张表或数据库的字符集从 utf8 切换至 utf8mb4 时,你可能会遇到麻烦。

例如,一个 TINYTEXT 列最多可容纳255个字节,这与85个三字节或63个四字节字符相关。 假设你有一个使用 utf8 的TINYTEXT列,但是必须能够包含超过63个字符。 考虑到这个要求,你不能将这个列转换为 utf8mb4,除非你也将数据类型改为一个更长的类型,比如TEXT - 因为如果你想用四字节字符填充它,你只能够 输入63个字符,但不是更多。

索引键也一样。 InnoDB存储引擎的最大索引长度为767字节,因此对于 utf8 或 utf8mb4 列,最多可以索引255或191个字符。 如果你目前有索引超过191个字符的 utf8 列,则在使用 utf8mb4 时,你必须要减少最大字符数。 因此,你必须将某些索引的VARCHAR(255)列更改为VARCHAR(191)

在微信的内置浏览器中,一旦你使用 utf8mb4 正确存储了昵称,那么在页面中,直接渲染表中存储的值,就会显示出 emoji 表情。

但是在普通浏览器中可能还会无法正常渲染。可以使用下面的工具函数进行“入库前编译,读取后反编译”来显示出 emoji 表情。

/**
* 处理含有 Emoji 字符的工具函数
* @param $msg 含有 Emoji 字符的字符串
* @param int $type type=0 表示写入数据库前的emoji转为HTML, type=1 表示读取之后渲染至HTML视图
* @return mixed|string
*/
function deal_emoji($msg, $type = 1) {
    if ($type == 0) {
        $msg = urlencode($msg);
        $msg = json_encode($msg);
    } else {
        $msg = preg_replace("#\\\u([0-9a-f]+)#ie", "iconv('UCS-2','UTF-8', pack('H4', '\\1'))", $msg);
        $msg = urldecode($msg);
        $msg = str_replace('"', "", $msg);
    }
    return $msg;
}