• PHP如何处理emoji表情存入utf8的数据库


    一般Mysql表设计时,都是用UTF8字符集的。把带有emoji的昵称字段往里面insert一下就没了,整个字段变成了空字符串。这是怎么回事呢?
    
    原来是因为Mysql的utf8字符集是3字节的,而emoji是4字节,这样整个昵称就无法存储了。这要怎么办呢

    1、使用utf8mb4字符集
    1、mysql的版本必须为v5.5.3或更高 2、把数据库的编码改成utf8mb4 -- UTF-8 Unicode 3、然后需要存储emoji表情的字段选择utf8mb4_general_ci 4、数据库连接也需要改为utf8mb4 这种方式可能带来的问题: 存储:在数据表中,对于变长的字段(如VARCHAR2,TEXT),utf8mb4最大可存储的字符可能少于utf8系列的collation;

       在索引中,对于文本类型的字段,utf8mb4可索引的字符少于utf8系列的collations。如InnoDB的索引最多使用767字节。

    如果使用utf8mb4,每一个字符都会预留4字节做索引,而utf8则预留3字节。故此前者是191个字符,后者是255个字符。 性能:由于以上原因,加上字符集大,utf8mb4的性能可能比utf8系列的collations低,

       可以参考stackoverfolow上的一个测试结果:http://stackoverflow.com/questions/766809/whats-the-difference-between-utf8-general-ci-and-utf8-unicode-ci,

       差异不是特别大。 运维:如果一个大的环境内,如果其他的数据库都是utf8模式,把其中某个库设置为utf8mb4模式,在后续交接运维可能会造成问题,遗留下坑。 上下游:数据库支持unicode的emoji存储,上下游不一定支持。比如mysql客户端驱动(低版本的jdbc就不行)可能不支持utf8mb4,或者DDL的中间件不支持utf8mb4。

       web端处理utf8mb4字符展示,这些都有可能影响emoji的存储活着展示。

    2、使用base64编码
    这种方法是可以,但是旧数据如果没有经过encode操作,取数据的时候如果统一进行decode的话,旧数据会丢失的。

    3、过滤emoji表情
    支持emoji表情是个麻烦的东西,有时即使能存储,也不一定能完美显示。可能会出现因emoji图片不够全而出现无法显示的情况。并且有些客户端可能还需要使用第三方类库,需要大量的emoji图片等。

    因此,如果emoji不是非要不可,我们可以把带有emoji内容的数据过滤掉,达到不影响其他数据的存储。

    // 过滤掉emoji表情
    function filterEmoji($str)
    {
       $str = preg_replace_callback('/./u',function (array $match) {
             return strlen($match[0]) >= 4 ? '' : $match[0];
          },$str);
       return $str;
    }
    4、文本转义emoji表情


    /**
    把用户输入的文本转义(主要针对特殊符号和emoji表情)
    */
    public function userTextEncode($str){
      if (!is_string($str)) return $str;
      if (!$str || $str=='undefined') return '';
      
      $text = json_encode($str); //暴露出unicode
      $text = preg_replace_callback("/(\u[ed][0-9a-f]{3})/i",function($str){
        return addslashes($str[0]);
      },$text); //将emoji的unicode留下,其他不动,这里的正则比原答案增加了d,因为我发现我很多emoji实际上是ud开头的,反而暂时没发现有ue开头。
      return json_decode($text);
    }
      
    /**
    解码上面的转义
    */
    public function userTextDecode($str){
      $text = json_encode($str); //暴露出unicode
      $text = preg_replace_callback('/\\\\/i',function($str){
        return '\';
      },$text); //将两条斜杠变成一条,其他不动
      return json_decode($text);
    }



    世界上最美的风景,是自己努力的模样
  • 相关阅读:
    完整的网站开发技术学习建议
    在微信小程序中绘制图表(part2)
    原创:新手布局福音!微信小程序使用flex的一些基础样式属性(一)
    第八届蓝桥杯第二题:等差素数列
    第七届蓝桥杯第四题:快速排序
    51Nod:1086背包问题 V2
    POJ:2386 Lake Counting(dfs)
    51Nod:1268 和为K的组合
    迭代器
    51Nod:1134 最长递增子序列
  • 原文地址:https://www.cnblogs.com/xiong-hua/p/11766143.html
Copyright © 2020-2023  润新知