今天在写博客的时候,使用了一些emoji的表情,在markdown编辑器中一切都正常。但是在Typecho系统中发布文章的时候,却报错了:
经过查询资料得知,如果 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_contents
、typecho_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. 改表 | 转换表为 utf8mb4 | ALTER TABLE ... | 修改 contents 、comments 等 |
3. 改配置 | 更新 config.inc.php | 'charset' => 'utf8mb4' | 强制连接使用 utf8mb4 |
4. 改 MySQL | 修改 my.cnf | character-set-server=utf8mb4 | 需重启 MySQL |
知识扩展
- mb4就是most bytes 4的意思,可以用来兼容四字节的unicode,存储与获取数据的时候,不用再考虑表情字符的编码与解码问题。如果你要存互联网emoji表情,就需要utf8mb4,而不是utf-8
- utf8mb4是utf8的超集,除了将编码改为utf8mb4外不需要做其他转换
- MySQL数据库的 “utf8”并不是真正概念里的 UTF-8,MySQL中的“utf8”编码只支持最大3字节每字符。真正的大家正在使用的UTF-8编码是应该能支持4字节每个字符,MySQL的开发者没有修复这个bug。他们在2010年增加了一个变通的方法:一个新的字符集“utf8mb4”,他们并没有对外公布(可能因为这个bug有点尴尬)。现在很多指南推荐用户使用“utf8”其实都错了
- 建议MySQL和MariaDB用户使用“utf8mb4”而不是“utf8”,毕竟现在是不管使用 Anroidz设备,还是 iOS 设备,如果插入包含有 emoji 表情符号的记录时就报错,还是很尴尬的
- 最重要一点,对数据库操作前,记得备份数据
- 为什么要把数据库的字符集设置成utf8mb4呢?以前一直用的都是utf8啊?utf8适用于不使用移动设备的互联网交互,utf8mb4适用于当前的移动设备互联网开发,因为移动设备中常常会有表情符号(emoji)的存储,它占用4个字节的存储空间,而utf8是3个字节,这样,用3个字节去存储4个字节的东西,很明显是存不下的,会报错,所以要用utf8mb4,并且utf8mb4是兼容utf8的,那么,就没有理由不用utf8mb4字符集了。
参考资料链接:https://juejin.cn/post/7098672368897228808(作者:JanYork_小简)【来源:稀土掘金】
评论