php过滤文字中的表情字符和mysql服务端对emoji的支持

本文介绍在项目开发中遇到Emoji表情的处理办法,包括过滤原理、PHP过滤方法、使用UTF8MB4字符集和Base64编码等解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.过滤emoji表情的原因

  在我们的项目开发中,emoji表情是个麻烦的东西,即使我们可以能存储,也不一定能完美显示,因为它的更新速度很快:在iOS以外的平台上,例如PC或者android。如果你需要显示emoji,就得准备一大堆emoji图片并使用第三方前端类库才行。即便如此,还是可能因为emoji图片不够全而出现无法显示的情况
在大多数业务场景下,emoji也不是非要不可的。我们可以适当地考虑干掉它,节约各种成本。

 

2.php过滤emoji原理

  Emoji (絵文字,词义来自日语えもじ,e-moji,moji在日语中的含义是字符)是一套起源于日本的12x12像素表情符号,由栗田穣崇(Shigetaka Kurit)创作,最早在日本网络及手机用户中流行。自苹果公司发布的iOS 5输入法中加入了emoji后,这种表情符号开始席卷全球,目前emoji已被大多数现代计算机系统所兼容的Unicode编码采纳,普遍应用于各种手机短信和社交网络中。近期,更是有不少网友用emoji图案玩猜字游戏,享受这种表情文化带来的乐趣。

 

关于emoji的发音:很多人第一眼见到emoji便会下意识将其误读作“一磨叽”,其实不然,emoji音译过来大概读作“诶磨叽”,当中“e”的发音颇似字母abc的a的发音。

 

最初日本的三大电信运营商各自有不同的字符定义,分别是DoCoMo、KDDI和Softbank。随着iOS内置了Softbank的版本,emoji在全球范围内风靡(iOS5版本以前)。而Google又自己定义了一套emoji字符。iOS5以后,apple采用了unicode定义的emoji字符(iOS5版本以后)。

 

unicode定义的emoji是四个字符,softbank为3个字符,emoji的四个字符从存储到展示对应没有做过考虑的系统来说,简直就是灾难。

 

3.针对unicode定义的emoji表情过滤

  ①.unicode定义的emoji是四个字符,根据这个原理进行过滤

  

复制代码
// 过滤掉emoji表情
function filter_Emoji($str)
{
    $str = preg_replace_callback(    //执行一个正则表达式搜索并且使用一个回调进行替换
            '/./u',
            function (array $match) {
                return strlen($match[0]) >= 4 ? '' : $match[0];
            },
            $str);

     return $str;
 }
复制代码

 

  

  ②. unicode emoji是4个字节,softbank定义的emoji占用3个字节存储,通过emoji for php ,我们可以把unicode的emoji方式转换为softbank方式,从而实现不修改数据库,就能存储emoji,相对于数据库层面的解决问题的方式,动作要小的多,并且也不会有性能,运维等方面的问题。但是有个不可避免的问题是,Softbank方式已经不再维护,所以新增加的emoji表情,Softbank中都没有,会造成部分emoji表情丢失的情况,对于这种情况不推荐使用。

 

  后续还有一些方法没有亲自实践过,但是给大家提供出来。

  

  1、使用utf8mb4字符集

 

  如果你的mysql版本>=5.5.3,你可以尝试直接将utf8直接升级为utf8mb4字符集
  这种4字节的utf8编码可完美兼容旧的3字节utf8字符集,并且可以直接存储emoji表情,是较好的解决方案之一。
  至于字节增大带来的性能损耗,根据自己的项目,自己估算吧....

 

  2、使用base64编码

 

  如果你因为某些原因无法使用utf8mb4字符集的话,你还可以使用base64来曲线救国
  使用例如base64_encode之类的函数编码过后的emoji可以直接存储在utf8字节集的数据表中,取出时decode一下即可

 

 

1.utf8mb4的最低mysql版本支持版本为5.5.3+,若不是,请升级到较新版本。

mysql版本查看命令请看:查看mysql版本的四种方法;mysql安装步骤请看:Linux中升级Mysql到Mysql最新版本的方法
2.修改database、table和column字符集。参考以下语句:
ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE table_name CHANGE column_name VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
3.修改mysql配置文件my.cnf(windows为my.ini)

my.cnf一般在etc/mysql/my.cnf位置。找到后请在以下三部分里添加如下内容:

[client]
default-character-set = utf8mb4

[mysql]
default-character-set = utf8mb4

[mysqld]
character-set-client-handshake = FALSE
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect='SET NAMES utf8mb4'

4.重启 MySQL Server、检查字符集

1.)重启命令参考:/etc/init.d/mysql restart

2.)输入命令:mysql,进入mysql命令行(如果提示没权限,可以尝试输入mysql -uroot -p你的密码)

3.)在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)

特别说明下:collation_connection/collation_database/collation_server如果是utf8mb4_general_ci,没有关系。但必须保证character_set_client/character_set_connection/character_set_database/character_set_results/character_set_server为utf8mb4。关于这些字符集配置是干什么用的,有什么区别,请参考:深入Mysql字符集设置

5.修改连接数据字符集设置uft8mb4

'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=192.168.1.130;dbname=',
'username' => '',
'password' => '',
'charset' => 'utf8mb4',
],

<think>好的,用户现在问的是在VC(Visual C++)中使用MySQL时应该选择什么字符编码最好。我需要先理解用户的需求,可能他们在开发一个C++应用程序,使用MySQL作为数据库,遇到了字符编码的问题,或者想预防乱码等情况。 首先,用户可能不太清楚字符编码的基本概念,比如UTF-8、GBK之类的区别,所以需要解释为什么选择特定的编码。然后,他们可能想知道在VC(Visual C++)环境下,如何设置MySQL字符集,确保从数据库到应用程序的数据传输过程中不会出现乱码。 接下来,我需要考虑MySQL的版本,不同版本可能有不同的默认编码。例如,MySQL 8.0默认使用utf8mb4,而旧版本可能使用latin1。所以需要建议用户使用utf8mb4,因为它支持更广泛的Unicode字符,包括表情符号等。 另外,VC++应用程序本身处理字符串的方式也很重要。如果用户使用的是多字节字符集还是Unicode,这会影响他们如何在代码中处理字符串。可能需要建议在VC项目中使用Unicode设置,这样MySQL的utf8mb4配合更好。 还要考虑连接MySQL时的字符集设置,比如在连接字符串中指定characterEncoding=utf8mb4,或者使用SET NAMES命令。同时,需要提醒用户注意MySQL的配置文件(my.ini或my.cnf)中的设置,确保服务器、数据库表的默认字符集都是utf8mb4。 可能用户在实际操作中遇到了乱码问题,比如数据插入或查询时出现问号或乱码,这时候需要检查各个环节的编码是否一致。例如,数据库、表、字段的字符集,连接器的配置,以及应用程序本身的编码设置。 另外,需要提到排序规则(collation),比如utf8mb4_unicode_ci,这会影响字符串比较排序的规则。正确的排序规则选择也很重要,尤其是在多语言环境下。 可能用户还会混淆utf8utf8mb4,因为在MySQL中,utf8实际上是阉割版的,只支持最多3个字节,而utf8mb4才是完整的4字节UTF-8编码。这点需要特别强调,避免用户误用utf8导致无法存储某些字符。 最后,总结最佳实践,包括统一使用utf8mb4,检查各层配置,使用合适的连接参数,以及在VC++中正确处理字符串。可能还需要给出示例代码,说明如何在连接数据库时设置字符集,比如使用MySQL Connector/C++时的参数设置。 需要确保回答结构清晰,步骤明确,用户能够按照指导一步步配置环境,避免遗漏关键点。同时提醒常见的陷阱,比如旧版本的MySQL支持utf8mb4,或者VC项目设置不正确导致的编码问题。</think>### MySQL 字符编码最佳实践(Visual C++ 开发场景) --- #### **核心原则**:**统一使用 `utf8mb4` 编码** > 在 Visual C++ 与 MySQL 交互场景中,`utf8mb4` 是唯一推荐的全兼容字符集,原因如下: > 1. 支持完整 Unicode(含 emoji 等 4 字节字符) > 2. 完美兼容现代多语言需求 > 3. 避免 MySQL 的 `utf8` 伪实现问题(MySQL 的 `utf8` 实际是阉割版) --- ### **完整配置流程** #### **1. MySQL 服务端配置** 修改 `my.ini`/`my.cnf`: ```ini [mysqld] character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci ``` #### **2. 数据库创建** ```sql CREATE DATABASE your_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; ``` #### **3. 表级定义** ```sql CREATE TABLE your_table ( id INT PRIMARY KEY, content VARCHAR(255) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; ``` #### **4. VC++ 连接设置** 使用 MySQL Connector/C++ 时需明确指定编码: ```cpp sql::ConnectOptionsMap connection_properties; connection_properties["hostName"] = "localhost"; connection_properties["userName"] = "root"; connection_properties["password"] = "123456"; connection_properties["characterEncoding"] = "UTF-8"; // 关键参数 connection_properties["useSSL"] = "false"; sql::Driver* driver = get_driver_instance(); sql::Connection* con = driver->connect(connection_properties); ``` --- ### **关键注意点** #### **编码一致性检查** ```sql -- 验证各层级编码 SHOW VARIABLES LIKE 'character_set%'; SHOW CREATE DATABASE your_db; SHOW CREATE TABLE your_table; ``` #### **VC++ 工程设置** 1. 项目属性 → 高级 → 字符集 → **使用 Unicode 字符集** 2. 字符串处理建议: ```cpp // 使用宽字符串(wstring)进行中间处理 std::wstring wsContent = L"中文内容"; // 转换为 UTF-8 格式传输到 MySQL std::string utf8Content = WideToUTF8(wsContent); ``` #### **连接参数陷阱** 错误配置示例(导致乱码): ```cpp // 错误:未明确指定编码 connection_properties["characterEncoding"] = ""; // 错误:使用错误编码标识 connection_properties["characterEncoding"] = "GBK"; ``` --- ### **编码问题诊断表** | 现象 | 可能原因 | 解决方案 | |-----------------------|---------------------------|------------------------------| | 中文显示为问号(???) | 传输层编码不匹配 | 检查连接字符串characterEncoding参数 | | 部分字符无法插入 | 使用`utf8`而非`utf8mb4` | 修改表字段字符集 | | 控制台输出乱码 | VC++控制台代码页设置错误 | 使用`system("chcp 65001")` | | 网页显示异常 | HTTP头未声明UTF-8 | 添加`Content-Type: text/html; charset=utf-8` | --- ### **性能优化建议** 1. **索引优化**:`utf8mb4` 字段建立前缀索引 ```sql ALTER TABLE log ADD INDEX (content(20)); ``` 2. **排序规则选择**: - 中文优先:`utf8mb4_zh_0900_as_cs`(MySQL 8.0+) - 通用场景:`utf8mb4_unicode_ci` --- ### **迁移旧数据方案** ```sql -- 转换已有数据库编码 ALTER DATABASE old_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- 转换表编码 ALTER TABLE old_table CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; ``` --- ### **特殊场景处理** 1. **BLOB类型处理**: ```cpp // 二进制数据应使用预处理语句 sql::PreparedStatement* pstmt = con->prepareStatement("INSERT INTO files(data) VALUES(?)"); std::istream* blob_data = new std::istringstream(binary_data); pstmt->setBlob(1, blob_data); ``` 2. **命令行工具编码**: ```bash mysql -u root -p --default-character-set=utf8mb4 ``` 通过统一使用 `utf8mb4` 编码体系,可确保从 VC++ 应用到 MySQL 存储的全链路字符兼容性。实际开发中需特别注意连接器配置与工程设置的匹配性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值