升级至MariaDB 10.6+nd_mysqli后utf8mb3表无法保存Emoji
问题原因分析
1. nd_mysqli驱动的字符集校验严格性提升
MariaDB 10.6搭配nd_mysqli驱动时,对字符集的一致性校验比旧版mysqli驱动更严格:
- WordPress默认会将数据库连接字符集设置为
utf8mb4(不管表本身的字符集),旧版mysqli驱动下,MariaDB 10.5会对utf8mb4(4字节)和utf8mb3(3字节)字符集的不匹配做宽松处理——要么静默将4字节Emoji转义为可存储的格式,要么忽略插入错误; - 升级到nd_mysqli后,驱动会严格校验客户端发送的字符编码与表字段的编码兼容性,4字节Emoji无法存入仅支持3字节的
utf8mb3字段,直接触发插入失败,但由于WordPress或服务器的日志配置问题,错误信息没有正常输出。
2. 旧数据能正常显示的原因
你之前的Emoji并非直接以4字节UTF-8格式存入utf8mb3表(这本身不可能,utf8mb3不支持4字节字符),而是WordPress的内置机制在插入时自动将Emoji转换为HTML实体(比如😀),这些实体是3字节以内的ASCII字符,完全符合utf8mb3的存储规则;前端显示时,浏览器会自动将实体解析为Emoji,所以你看起来像是直接存储了Emoji。
3. old_mode=""设置无效的原因
old_mode参数控制的是MariaDB对旧版本兼容行为的开关(比如是否允许无效日期、自动创建用户等),和utf8的别名映射无关:
- MariaDB 10.6及之后,
utf8默认就是utf8mb3的别名,修改old_mode不会改变这个映射关系; - 若要让默认
utf8指向utf8mb4,需要在my.cnf中配置character_set_server=utf8mb4和collation_server=utf8mb4_unicode_ci,但这也无法解决已存在的utf8mb3表的问题。
总结
升级后无法保存的本质是:nd_mysqli不再允许4字节字符插入utf8mb3字段,而编辑旧文章时,编辑器会将原本存储的HTML实体还原为真实的4字节Emoji字符,提交时触发插入失败。
内容的提问来源于stack exchange,提问作者Nicolas Laruelle - EasyHoster
相关产品推荐
相关产品推荐

