为什么 utf8 装不下 emoji
MySQL 早期的 utf8 字符集实际是 utf8mb3,最多 3 字节,只能存基本多文种平面字符;而 emoji 与部分生僻字属于补充平面,需要 4 字节。织梦默认 utf8 时,会员昵称、评论、留言中一旦出现 emoji,写入会报 Incorrect string value 或被截断为 ?。解决办法是把字符集升级为 utf8mb4,它在 MySQL 5.5.3+ 完整支持 4 字节 UTF-8。
升级前检查
- MySQL 版本 ≥ 5.5.3,建议 5.7+。
- 升级前完整备份数据库:
mysqldump --default-character-set=utf8mb4 dedecms > dedecms.sql - 检查织梦版本,老版本可能存在硬编码 utf8 的地方,需配套修改。
- 评估磁盘占用:utf8mb4 索引最大长度 3072 字节,影响 VARCHAR 长度上限。
步骤一:修改 MySQL 配置
编辑 /etc/my.cnf(或 mysqld.cnf),在对应段加入:
[client]
default-character-set=utf8mb4
[mysql]
default-character-set=utf8mb4
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
# 防止索引长度超限
innodb_large_prefix=ON
innodb_file_format=Barracuda
innodb_default_row_format=DYNAMIC
重启 MySQL:systemctl restart mysqld,验证:
SHOW VARIABLES LIKE 'character_set%';
SHOW VARIABLES LIKE 'collation%';
-- 期望 character_set_server=utf8mb4
-- 期望 collation_server=utf8mb4_unicode_ci
步骤二:转换库与表字符集
对整个织梦库执行 ALTER,把库与所有表、字段转为 utf8mb4:
-- 修改库默认字符集
ALTER DATABASE dedecms CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 修改单张表(含所有 VARCHAR/TEXT 字段)
ALTER TABLE dede_archives
CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 批量生成所有表的 ALTER 语句
SELECT CONCAT('ALTER TABLE `', table_name, '` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;')
FROM information_schema.tables
WHERE table_schema='dedecms'
AND table_type='BASE TABLE';
步骤三:修改织梦程序连接
编辑 data/common.inc.php,把语言改为 utf8mb4:
$cfg_db_language='utf8mb4';
检查 include/dedesql.class.php 中 mysql_query("SET NAMES ..."),确保使用配置变量而非硬编码 utf8:
// 找到类似代码,确保是 $cfg_db_language 而非写死 'utf8'
$this->SetQuery("SET NAMES ".$this->dbLanguage);
部分老版本织梦在 include/common.inc.php 也有 SET NAMES,需一并排查。
步骤四:验证 emoji 写入
在会员昵称或评论框输入 emoji(如表情符号)提交,再用 SQL 查看是否正常存储:
SELECT uname FROM dede_member WHERE mid=1;
-- 期望结果中 emoji 正常显示而非 ???
同时检查页面编码,确保模板文件本身以 UTF-8 无 BOM 保存,HTML head 中 <meta charset="UTF-8">。
常见坑点
- 索引长度:utf8mb4 下 VARCHAR(255) 索引达 1020 字节,需启用 large_prefix。
- 连接驱动:旧 mysql_* 扩展可能不识别 utf8mb4,建议用 mysqli 或 PDO。
- 静态生成页:HTML 文件本身要 UTF-8,否则即使库正确页面仍乱码。
- 备份恢复:mysqldump 导出时必须
--default-character-set=utf8mb4。 - 第三方插件:检查采集、推送等插件是否硬编码 utf8。
建议与行动
utf8mb4 升级建议在站点低峰期一次性完成,避免库表字符集不一致引发写入异常。升级后用一段时间的 emoji 评论与会员昵称做回归测试,确认全链路无截断。同时把字符集要求写入织梦二次开发规范,约束后续插件与模板都按 utf8mb4 编码,让站点长期兼容 emoji 与多语言字符。