没有不值得去解决的问题,也没有不值得去学习的技术!

WordPress 代码块中 Emoji 显示异常?三步彻底解决

如图3:前端代码块中 Emoji 变成 HTML 实体

在 WordPress 中展示包含 Emoji 的代码片段时,常常遇到 Emoji 被转成 &#x1f389; 或 <img> 标签的问题。本文记录一次完整的排查与解决过程。

问题现象

在 WordPress 古腾堡编辑器的代码块中,写入如下 PHP 代码,如图1:

在 WordPress 古腾堡编辑器的代码块中,写入如下 PHP 代码,如图1
PHP
echo "\n🎉 全部处理完成!\n";
echo "📊 统计:\n";
echo "   已处理新标签: {$processed}\n";
echo "   已跳过已有翻译: {$skipped}\n";
echo "\n✅ 所有标签都已经处理完毕,和手动添加的完全一样!\n";

保存文章后,前端显示的却是:

PHP
echo "\n🎉 全部处理完成!\n";
echo "📊 统计:\n";
...

或者更糟糕的情况,Emoji 变成了长长的 <img> 标签:

PHP
echo "\n<img draggable="false" ... src=".../1f389.svg"> 全部处理完成!\n";

如图2:编辑器内正常显示 Emoji

如图2:编辑器内正常显示 Emoji

如图3:前端代码块中 Emoji 变成 HTML 实体

如图3:前端代码块中 Emoji 变成 HTML 实体

如图8:前端代码块中 Emoji 变成 img 标签

如图8:前端代码块中 Emoji 变成 img 标签

原因分析

这个问题由两个独立机制叠加引起:

  1. 数据库字符集不支持 Emoji
    旧版 MySQL 的 utf8 字符集只支持 3 字节字符,而 Emoji 占用 4 字节。当表或字段是 utf8 时,WordPress 会在保存前自动将 Emoji 转成 HTML 实体(如 🎉 → &#x1f389;),避免数据库报错。 如图4:查询发现核心表字符集为 utf8_general_ci
  2. 前端输出时的 Emoji 图片替换
    即使数据库已支持 utf8mb4,WordPress 仍默认将 Emoji 字符替换为从 CDN 加载的 SVG 图片(通过 wp_staticize_emoji 过滤器),导致代码块内出现 <img> 标签。
如图4:查询发现核心表字符集为 utf8_general_ci

对于使用 SyntaxHighlighter Evolved 等代码高亮插件的用户,这两种转换都会彻底破坏代码的原样展示。

解决方案

第一步:检查并升级数据库字符集

确保你的 WordPress 数据库使用 utf8mb4 字符集。

  1. 通过 phpMyAdmin 或 SQL 查询当前表的字符集:
SQL
   SELECT TABLE_NAME, TABLE_COLLATION
   FROM information_schema.TABLES
   WHERE TABLE_SCHEMA = '你的数据库名';

如图4:查询结果示例(部分表为 utf8_general_ci)

如图4:查询结果示例(部分表为 utf8_general_ci)
  1. 如果 wp_posts、wp_options、wp_terms 等核心表显示 utf8_general_ci,则需要转换:
SQL
-- SELECT TABLE_NAME, TABLE_COLLATION FROM information_schema.TABLES WHERE TABLE_SCHEMA = '你的数据库名'; 的查询结果如下:
INSERT INTO `TABLES` (`TABLE_NAME`,`TABLE_COLLATION`) VALUES ('wp_cky_banners','utf8mb4_unicode_520_ci');
INSERT INTO `TABLES` (`TABLE_NAME`,`TABLE_COLLATION`) VALUES ('wp_cky_cookie_categories','utf8mb4_unicode_520_ci');
INSERT INTO `TABLES` (`TABLE_NAME`,`TABLE_COLLATION`) VALUES ('wp_cky_cookies','utf8mb4_unicode_520_ci');
INSERT INTO `TABLES` (`TABLE_NAME`,`TABLE_COLLATION`) VALUES ('wp_cmplz_cookiebanners','utf8mb4_unicode_520_ci');
INSERT INTO `TABLES` (`TABLE_NAME`,`TABLE_COLLATION`) VALUES ('wp_cmplz_cookies','utf8mb4_unicode_520_ci');
INSERT INTO `TABLES` (`TABLE_NAME`,`TABLE_COLLATION`) VALUES ('wp_cmplz_services','utf8mb4_unicode_520_ci');
INSERT INTO `TABLES` (`TABLE_NAME`,`TABLE_COLLATION`) VALUES ('wp_commentmeta','utf8_general_ci');
INSERT INTO `TABLES` (`TABLE_NAME`,`TABLE_COLLATION`) VALUES ('wp_comments','utf8_general_ci');
INSERT INTO `TABLES` (`TABLE_NAME`,`TABLE_COLLATION`) VALUES ('wp_links','utf8_general_ci');
INSERT INTO `TABLES` (`TABLE_NAME`,`TABLE_COLLATION`) VALUES ('wp_options','utf8_general_ci');
INSERT INTO `TABLES` (`TABLE_NAME`,`TABLE_COLLATION`) VALUES ('wp_orgseriesicons','utf8mb4_general_ci');
INSERT INTO `TABLES` (`TABLE_NAME`,`TABLE_COLLATION`) VALUES ('wp_post_views','utf8mb4_unicode_520_ci');
INSERT INTO `TABLES` (`TABLE_NAME`,`TABLE_COLLATION`) VALUES ('wp_postmeta','utf8_general_ci');
INSERT INTO `TABLES` (`TABLE_NAME`,`TABLE_COLLATION`) VALUES ('wp_posts','utf8_general_ci');
INSERT INTO `TABLES` (`TABLE_NAME`,`TABLE_COLLATION`) VALUES ('wp_term_relationships','utf8_general_ci');
INSERT INTO `TABLES` (`TABLE_NAME`,`TABLE_COLLATION`) VALUES ('wp_term_taxonomy','utf8_general_ci');
INSERT INTO `TABLES` (`TABLE_NAME`,`TABLE_COLLATION`) VALUES ('wp_termmeta','utf8mb4_unicode_ci');
INSERT INTO `TABLES` (`TABLE_NAME`,`TABLE_COLLATION`) VALUES ('wp_terms','utf8_general_ci');
INSERT INTO `TABLES` (`TABLE_NAME`,`TABLE_COLLATION`) VALUES ('wp_usermeta','utf8_general_ci');
INSERT INTO `TABLES` (`TABLE_NAME`,`TABLE_COLLATION`) VALUES ('wp_users','utf8_general_ci');
INSERT INTO `TABLES` (`TABLE_NAME`,`TABLE_COLLATION`) VALUES ('wp_yoast_indexable','utf8mb4_unicode_520_ci');
INSERT INTO `TABLES` (`TABLE_NAME`,`TABLE_COLLATION`) VALUES ('wp_yoast_indexable_hierarchy','utf8mb4_unicode_520_ci');
INSERT INTO `TABLES` (`TABLE_NAME`,`TABLE_COLLATION`) VALUES ('wp_yoast_migrations','utf8mb4_unicode_520_ci');
INSERT INTO `TABLES` (`TABLE_NAME`,`TABLE_COLLATION`) VALUES ('wp_yoast_primary_term','utf8mb4_unicode_520_ci');
INSERT INTO `TABLES` (`TABLE_NAME`,`TABLE_COLLATION`) VALUES ('wp_yoast_seo_links','utf8_general_ci');


-- 需要转换的 SQL 如下:

-- 文章相关表
ALTER TABLE wp_posts CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE wp_postmeta CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- 选项表(可能存有包含 Emoji 的选项值)
ALTER TABLE wp_options CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- 分类/标签表
ALTER TABLE wp_terms CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE wp_term_taxonomy CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE wp_term_relationships CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;


-- 评论表(如果评论可能包含 Emoji)
ALTER TABLE wp_comments CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE wp_commentmeta CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- 用户表(可选)
ALTER TABLE wp_users CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE wp_usermeta CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- 友情链接表(如果有)
ALTER TABLE wp_links CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

ALTER TABLE wp_yoast_seo_links CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

如图5:执行 ALTER TABLE 转换

如图5:执行 ALTER TABLE 转换

如图6:执行 ALTER TABLE 转换后的结果
  1. 在 wp-config.php 中强制指定字符集,如图7:
PHP
   define('DB_CHARSET', 'utf8mb4');
   define('DB_COLLATE', 'utf8mb4_unicode_ci');
在 wp-config.php 中强制指定字符集,如图7:

⚠️ 注意:操作前务必备份数据库!

第二步:禁用前端 Emoji 图片替换

在主题的 functions.php 中添加以下代码:

PHP
// 彻底禁用 WordPress 前端 Emoji 转换为图片
remove_filter( 'the_content', 'wp_staticize_emoji' );
remove_filter( 'the_excerpt', 'wp_staticize_emoji' );
remove_filter( 'comment_text', 'wp_staticize_emoji' );

// 同时移除 Emoji 的 JS/CSS(提升加载速度)
remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
remove_action( 'wp_print_styles', 'print_emoji_styles' );
remove_action( 'admin_print_styles', 'print_emoji_styles' );
remove_filter( 'the_content_feed', 'wp_staticize_emoji' );
remove_filter( 'comment_text_rss', 'wp_staticize_emoji' );
remove_filter( 'wp_mail', 'wp_staticize_emoji_for_email' );

如图10:在 functions.php 中添加禁用代码

如图10:在 functions.php 中添加禁用代码

第三步:清理已有文章中的异常内容

  • 新文章:按以上两步配置后,直接使用 Emoji 保存即可正常显示。
  • 旧文章:如果之前已被转换成 HTML 实体或 <img> 标签,需要手动重新编辑,将实体(如 &#x1f389;)替换回原始 Emoji 字符(🎉),然后更新文章。

如图9:在古腾堡编辑器中替换实体为 Emoji

如图9:在古腾堡编辑器中替换实体为 Emoji

如图11:最终前端显示效果(Emoji 原样展示)

如图11:最终前端显示效果(Emoji 原样展示)

总结

现象原因解决方法
保存后 Emoji 变成 &#x...;数据库字符集不是 utf8mb4升级表为 utf8mb4
前端显示 <img> 标签wp_staticize_emoji 过滤器在 functions.php 中移除该过滤器

通过以上三步,你的 WordPress 站点即可完美在代码块中展示包含 Emoji 的代码片段,不再被任何转换干扰。如果使用的是 SyntaxHighlighter Evolved 或其他代码高亮插件,同样适用本方案。


本文基于真实问题排查记录整理,所有操作已在 WordPress 7.x + PHP 8.x 环境下验证通过。

关于作者 · 持续学习与技术实践

我是一名拥有 15 年以上开发经验的技术从业者,自 2013 年起持续运营个人技术博客,记录工作与个人项目中遇到的真实问题,以及解决问题过程中的探索、实践和思考。

除了技术写作,我也在持续开发和维护自己的独立项目,探索新技术和新工具在实际场景中的应用。我始终相信,没有不值得去解决的问题,也没有不值得去学习的技术。

如果这篇文章对你有所帮助,欢迎浏览博客中的其他文章,也欢迎交流技术经验与想法。

关于我  ·  GitHub  ·  邮件联系