在不升级 mysql 的情况下直接使用 mysql utf8 存储 超过三个字节的 emoji 表情

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
云数据库 RDS MySQL Serverless,价值2615元额度,1个月
简介: 由于现在数据库的版本是5.5.2,但是看网上说要直接存储emoji表情,需要升级到5.5.3然后把字符集设置为utf8mb4,但是升级数据库感觉属于敏感操作。 PHP 版本 考虑了多久之后直接考虑使用正则来替换,但是emoji表情的unicode码太多了,在网上找了一份代码,还是2年前更新的,想

由于现在数据库的版本是5.5.2,但是看网上说要直接存储emoji表情,需要升级到5.5.3然后把字符集设置为utf8mb4,但是升级数据库感觉属于敏感操作。

考虑了多久之后直接考虑使用正则来替换,但是emoji表情的unicode码太多了,在网上找了一份代码,还是2年前更新的,想了想还是算了。

PHP 版本

最简单的办法就是直接找到接受到的文本中的字符串中4个字节的内容,做rawurlencode编码,再入库。输出的时候再替换回来,然后再用rawurldecode转码回unicode到手机再解析为emoji表情。

获取字符串长度mb_strlen,按字符来截取字符串mb_substrmb_strcut是按字节来截取,有区别)。

存储

$strEncode = '';
 
$length = mb_strlen($str,'utf-8');
 
for ($i=0; $i < $length; $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";

20150204001219_21486

php 就这么轻松愉快的解决了。

Java 版本

考虑到想使用php里面的套路,对原字符串逐个字符获取其长度,如果超过3个字节,那么则编码下,就能存储了,依照上次的经验,我写了如下代码

String a = "\uD83D\uDE01";// 一个 emoji 表情
byte[] bytes = a.getBytes("utf-8");
System.out.println(bytes.length);// 输出 4

单个单个的来,能获取到正确的字节数,但是如何保证切割字符串的时候是正确的呢?我找遍了城市所有的街道,都没有,找到我要的方法.

import java.net.URLEncoder;
import java.net.URLDecoder;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.io.UnsupportedEncodingException;
 
public class test{
 
    public static void main(String[] args) throws Exception { 
        String content = args[0];
        System.out.println(content);
        
        int strLength = content.length();
        
        String filterContent = emojiFilter(content);
        System.out.println(filterContent);
 
        String emojiStr = emojiRecovery(filterContent);
        System.out.println(emojiStr);
    }
 
    private static String emojiFilter(String str){
        String patternString = "([\\x{10000}-\\x{10ffff}\ud800-\udfff])";
 
        Pattern pattern = Pattern.compile(patternString);
        Matcher matcher = pattern.matcher(str);
 
        StringBuffer sb = new StringBuffer();
        while(matcher.find()) {
            try {
                matcher.appendReplacement(sb, "[[EMOJI:" + URLEncoder.encode(matcher.group(1),"UTF-8") + "]]");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        matcher.appendTail(sb);
 
        return sb.toString();
    }
 
    private static String emojiRecovery(String str){
        String patternString = "\\[\\[EMOJI:(.*?)\\]\\]";
 
        Pattern pattern = Pattern.compile(patternString);
        Matcher matcher = pattern.matcher(str);
 
        StringBuffer sb = new StringBuffer();
        while(matcher.find()) {
            try {
                matcher.appendReplacement(sb, URLDecoder.decode(matcher.group(1),"UTF-8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        matcher.appendTail(sb);
 
        return sb.toString();
    }
}

20150610235033_89389

20150611103503_66714

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
1月前
|
存储 SQL NoSQL
mysql存储过程和存储函数
mysql存储过程和存储函数
|
1月前
|
存储 JSON 关系型数据库
轻松入门MySQL:MySQL字段类型精解,优化存储结构,助力系统高效运行(2)
轻松入门MySQL:MySQL字段类型精解,优化存储结构,助力系统高效运行(2)
|
1月前
|
SQL 存储 关系型数据库
轻松入门MySQL:简明教程解析数据存储与管理(1)
轻松入门MySQL:简明教程解析数据存储与管理(1)
|
2月前
|
存储 缓存 关系型数据库
MySQL的varchar水真的太深了——InnoDB记录存储结构
varchar(M) 能存多少个字符,为什么提示最大16383?innodb怎么知道varchar真正有多长?记录为NULL,innodb如何处理?某个列数据占用的字节数非常多怎么办?影响每行实际可用空间的因素有哪些?本篇围绕innodb默认行格式dynamic来说说原理。
845 6
MySQL的varchar水真的太深了——InnoDB记录存储结构
|
2月前
|
SQL 关系型数据库 MySQL
【MySQL技术专题】「问题实战系列」深入探索和分析MySQL数据库的数据备份和恢复实战开发指南(8.0版本升级篇)
【MySQL技术专题】「问题实战系列」深入探索和分析MySQL数据库的数据备份和恢复实战开发指南(8.0版本升级篇)
102 0
|
3天前
|
存储 关系型数据库 MySQL
MySQL是怎样存储数据的?
MySQL是怎样存储数据的?
|
1月前
|
存储 Kubernetes 关系型数据库
使用Helm管理创建MYSQL并使用外置存储
使用Helm管理创建MYSQL并使用外置存储
45 0
|
3月前
|
安全 关系型数据库 MySQL
MySQL注入 -- 宽字节注入
MySQL注入 -- 宽字节注入
20 0
|
2天前
|
关系型数据库 MySQL 数据库
docker MySQL删除数据库时的错误(errno: 39)
docker MySQL删除数据库时的错误(errno: 39)
10 0
|
2天前
|
关系型数据库 MySQL 数据库连接
用Navicat备份Mysql演示系统数据库的时候出:Too Many Connections
用Navicat备份Mysql演示系统数据库的时候出:Too Many Connections

推荐镜像

更多