关于在Typecho中无法发布包含emoji表情的文章

今天在写博客的时候,使用了一些emoji的表情,在markdown编辑器中一切都正常。但是在Typecho系统中发布文章的时候,却报错了:
2025-04-13 11.07.36.png

经过查询资料得知,如果 Typecho 无法正常存储或显示 Emoji 表情(😊👉📌 等),一般是因为 MySQL 数据库的字符集和排序规则不支持 4 字节的 UTF-8(utf8mb4)。以下是完整的解决方案:


1. 修改 MySQL 数据库字符集

Typecho 默认使用 utf8(仅支持 3 字节字符,无法存储 Emoji),需要改为 utf8mb4(支持 4 字节)。

(1)修改数据库

登录 MySQL/MariaDB,执行:

-- 修改数据库字符集(将 your_db_name 替换为 Typecho 数据库名)
ALTER DATABASE your_db_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;

(2)修改数据表

Typecho 主要涉及以下表:typecho_contentstypecho_comments 等。

alter table typecho_comments convert to character set utf8mb4 collate utf8mb4_general_ci;
alter table typecho_contents convert to character set utf8mb4 collate utf8mb4_general_ci;
alter table typecho_fields convert to character set utf8mb4 collate utf8mb4_general_ci;
alter table typecho_metas convert to character set utf8mb4 collate utf8mb4_general_ci;
alter table typecho_options convert to character set utf8mb4 collate utf8mb4_general_ci;
alter table typecho_relationships convert to character set utf8mb4 collate utf8mb4_general_ci;
alter table typecho_users convert to character set utf8mb4 collate utf8mb4_general_ci;

2. 修改 Typecho 的数据库连接配置

config.inc.php 中强制设定 MySQL 连接字符集:

/** 数据库连接参数 */
$db = new Typecho_Db('Mysql', 'typecho_');
$db->addServer(array (
    'host' => 'localhost',
    'user' => 'root',
    'password' => 'your_password',
    'charset' => 'utf8mb4',  // 关键参数,覆盖默认的 utf8
    'port' => '3306',
    'database' => 'your_db_name',
), Typecho_Db::READ | Typecho_Db::WRITE);
Typecho_Db::set($db);

3. 检查 MySQL 版本与配置

(1)确保 MySQL >= 5.5.3

  • 只有 MySQL 5.5.3 以上 才支持 utf8mb4,执行 SELECT version(); 确认版本。

(2)修改 MySQL 全局配置

my.cnf(Linux)或 my.ini(Windows)中增加:

[client]
default-character-set = utf8mb4

[mysql]
default-character-set = utf8mb4

[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci

然后重启 MySQL(这一步很关键!!!):

# Linux
sudo systemctl restart mysql

# Windows(服务管理界面重启 MySQL)

4. 特殊情况处理

(1)插件/主题的额外兼容

某些插件/主题可能硬编码 utf8,需手动修改:

  • 检查插件代码中是否有 SET NAMES utf8,改为 SET NAMES utf8mb4
  • 主题的自定义 JS/CSS 需确保支持 UTF-8 解析。

(2)服务器环境检查

  • PHP 版本 ≥ 5.5(确保 mbstring 扩展支持 utf8mb4)。
  • HTTP 头部 确认无强制 charset=utf-8(可通过浏览器开发者工具检查)。

5. 验证是否生效

(1)存储测试

在博客文章或评论中尝试插入 Emoji(如 😊),保存后查看数据库:

  • 通过命令行或 phpMyAdmin 检查数据是否以 utf8mb4 存储。

(2)显示测试

刷新页面,确认 Emoji 正常显示(而不是变成 ? 或乱码)。


总结

步骤操作命令/代码示例备注
1. 改数据库修改 DB 字符集ALTER DATABASE ...针对 Typecho 的数据库
2. 改表转换表为 utf8mb4ALTER TABLE ...修改 contentscomments
3. 改配置更新 config.inc.php'charset' => 'utf8mb4'强制连接使用 utf8mb4
4. 改 MySQL修改 my.cnfcharacter-set-server=utf8mb4需重启 MySQL

知识扩展

  1. mb4就是most bytes 4的意思,可以用来兼容四字节的unicode,存储与获取数据的时候,不用再考虑表情字符的编码与解码问题。如果你要存互联网emoji表情,就需要utf8mb4,而不是utf-8
  2. utf8mb4是utf8的超集,除了将编码改为utf8mb4外不需要做其他转换
  3. MySQL数据库的 “utf8”并不是真正概念里的 UTF-8,MySQL中的“utf8”编码只支持最大3字节每字符。真正的大家正在使用的UTF-8编码是应该能支持4字节每个字符,MySQL的开发者没有修复这个bug。他们在2010年增加了一个变通的方法:一个新的字符集“utf8mb4”,他们并没有对外公布(可能因为这个bug有点尴尬)。现在很多指南推荐用户使用“utf8”其实都错了
  4. 建议MySQL和MariaDB用户使用“utf8mb4”而不是“utf8”,毕竟现在是不管使用 Anroidz设备,还是 iOS 设备,如果插入包含有 emoji 表情符号的记录时就报错,还是很尴尬的
  5. 最重要一点,对数据库操作前,记得备份数据
  6. 为什么要把数据库的字符集设置成utf8mb4呢?以前一直用的都是utf8啊?utf8适用于不使用移动设备的互联网交互,utf8mb4适用于当前的移动设备互联网开发,因为移动设备中常常会有表情符号(emoji)的存储,它占用4个字节的存储空间,而utf8是3个字节,这样,用3个字节去存储4个字节的东西,很明显是存不下的,会报错,所以要用utf8mb4,并且utf8mb4是兼容utf8的,那么,就没有理由不用utf8mb4字符集了。

参考资料链接:https://juejin.cn/post/7098672368897228808(作者:JanYork_小简)【来源:稀土掘金】

评论

等风等雨等你来