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

重新安装 Yoast SEO 后旧文章打不开:一次 WPCode Snippet 重复声明函数导致的 WordPress 致命错误排查记录

【图5:旧文章打开时出现 WordPress 致命错误】

作者:

,

博客搜索引擎优化日志

收到 Google Search Console 的邮件:新原因导致网站 http://www.shuijingwanwq.com/ 上的网页无法被编入索引。如图1

(1) Google网页无法编入索引?我这样解决了

验证通过后,在左侧菜单找到「站点地图」,输入 `/wp-sitemap.xml`,点击提交即可(如图1)

(2) 五大搜索引擎站点地图提交全记录:从Google到搜狗,我的实操经验分享

sitemap采用邀请制,当您的网站存在原创或不可替代内容或不能被搜狗spider正确抓取时,才会开通sitemap权限。

(3) 搜狗Sitemap权限申请记录:从审核通过到提交申请的全流程

所有主体、验证、备案配置全部完成后,进入核心的收录配置环节:【资源提交 - 普通收录 - 资源提交 - sitemap】,发现页面额度显示异常(如图3)

(4) 百度搜索资源平台新站完整收录实操记录(个人主体/自适应站/新站考察期问题解决)

美国流量占 20%,日本 10%,香港 16%,台湾 9%

(5) 技术博客英文站索引与低价值标签处理

中文站点地图:`https://www.你的域名.com/wp-sitemap-posts-post-1.xml` → 显示“致命错误”如图2

(6) 修复 WordPress 致命错误:从站点地图报错到恢复正常

Bing 明确指出了 4.2K 个页面存在“内容质量”问题

(7) 博客 SEO 诊断记录:近 15000 页面未被索引的成因与优化清单

点击表头的“总数”进行排序,数量为 0 的标签会集中在前几页。

(8) 彻底清理 WordPress 空标签:消除软 404,拯救抓取预算

/tag/bsc/ 网页源代码中成功出现 noindex 标签

(9) 博客 SEO 诊断记录:薄内容标签页 noindex 方案实战与多语言测试验证

“0秒访问”主要来自标签页

(10) WordPress Tag SEO优化实战:用WPCode实现“低内容标签页 noindex”完整踩坑与修复记录

图1:Bing整体流量趋势(下降起点)

(11) WordPress主题切换导致Bing流量下降实录(进行中):一次站点结构变更的SEO复盘

【图5:旧文章打开时出现 WordPress 致命错误】

(12) 重新安装 Yoast SEO 后旧文章打不开:一次 WPCode Snippet 重复声明函数导致的 WordPress 致命错误排查记录

最近我重新安装并启用了 Yoast SEO 免费版,原本只是想恢复 WordPress 文章的 SEO 标题、Meta Description、XML Sitemap 等基础功能。

一开始看起来一切都很顺利。Yoast SEO 成功安装后,系统提示可以进入首次配置向导。

【图1:Yoast SEO 安装成功页面】
【图1:Yoast SEO 安装成功页面】

但是在后续测试过程中,我发现了一个比较隐蔽的问题:

新文章可以正常打开;

旧文章中的某一篇却直接出现 WordPress 致命错误。

这篇文章记录一下完整排查过程。这个问题表面看起来像是 Yoast SEO 引起的,但最终发现真正原因并不是 Yoast,而是 WPCode 中一个自定义 PHP Snippet 的函数重复声明问题。

一、重新安装 Yoast SEO 免费版

我这次重新安装的是 Yoast SEO 免费版。

安装完成后,Yoast 会提示进入 First-time configuration,也就是首次配置向导。

【图2:Yoast SEO 首次配置入口】
【图2:Yoast SEO 首次配置入口】

进入配置向导后,第一步是 SEO 数据优化。这个过程会让 Yoast 扫描网站已有内容,并生成它自己的 SEO 数据索引。

【图3:Yoast SEO 正在进行 SEO 数据优化】
【图3:Yoast SEO 正在进行 SEO 数据优化】

因为我的博客文章数量比较多,所以这个步骤需要等待一会儿。

等优化完成后,页面显示:

We’ve successfully analyzed your site & optimized your SEO data!

【图4:Yoast SEO 数据优化完成】
【图4:Yoast SEO 数据优化完成】

到这里为止,Yoast SEO 本身的安装与基础初始化都没有问题。

二、异常现象:新文章正常,旧文章打不开

在启用 Yoast SEO 后,我测试了一篇新文章:

这篇文章可以正常打开。

但是另一篇 2021 年写的旧文章:

却出现了 WordPress 致命错误。

页面提示:

此站点遇到了致命错误。

【图5:旧文章打开时出现 WordPress 致命错误】
【图5:旧文章打开时出现 WordPress 致命错误】

这就比较容易误判。

因为现象是:

停用 Yoast SEO 后,旧文章恢复正常;

启用 Yoast SEO 后,旧文章打不开;

所以第一感觉很容易认为是 Yoast SEO 与旧文章内容结构不兼容。

但实际上,后面的日志证明,Yoast SEO 更像是“触发器”,并不是根因。

三、先确认后台编辑页是否正常

为了判断是不是文章内容本身彻底损坏,我先打开这篇旧文章的后台编辑页。

结果后台编辑页可以正常打开。

【图6:旧文章后台编辑页可以正常打开】
【图6:旧文章后台编辑页可以正常打开】

这篇旧文章使用的是 Classic Block 旧式内容结构,并且正文中有旧的 caption 图片短代码。

但后台能打开,说明文章数据本身并没有完全损坏。

问题更可能发生在前台渲染阶段。

四、查看 PHP-FPM 日志,定位真正错误

接下来通过服务器 SSH 查看 PHP-FPM 日志。

执行命令:

Bash
tail -n 80 /usr/local/php/var/log/php-fpm.log

日志中出现了关键报错:

Plaintext
PHP Fatal error: Cannot redeclare custom_desc_and_ads_inserter()

更完整的信息指向 WPCode 的代码执行器:

Plaintext
wp-content/plugins/insert-headers-and-footers/includes/class-wpcode-snippet-execute.php

也就是说,真正导致 WordPress 致命错误的,并不是 Yoast SEO 插件目录下的代码,而是 WPCode / Insert Headers and Footers 执行的某个 PHP Snippet。

这个函数名也很熟悉:

PHP
custom_desc_and_ads_inserter()

它来自我之前写的一个 PHP Snippet:

完美替代 16 条 Ad Inserter 规则的 PHP 代码

这个 Snippet 的作用,是根据文章语言、系列、分类等条件,在文章底部自动插入不同的推荐说明、联盟链接或技术服务咨询区块。

五、为什么新文章能打开,旧文章却打不开?

这个问题比较有迷惑性。

如果是 Yoast SEO 本身坏了,理论上所有文章都应该打不开。

但实际情况是:

新文章正常;

部分旧文章异常;

停用某个 WPCode Snippet 后恢复正常;

重新启用 Snippet 后再次异常。

这说明问题不是“Yoast SEO 导致所有文章崩溃”,而是某个 Snippet 在特定页面执行路径下被重复加载,最终重复声明了同一个 PHP 函数。

PHP 中函数不能重复声明。

如果同一个请求中执行了两次:

PHP
function custom_desc_and_ads_inserter() {
    // ...
}

就会触发:

Plaintext
Cannot redeclare custom_desc_and_ads_inserter()

Yoast SEO 启用后,前台页面渲染过程发生了一些变化,可能让原本隐藏的 WPCode Snippet 加载问题暴露出来。

所以更准确的判断是:

Yoast SEO 是触发器;

WPCode Snippet 中不安全的函数声明才是根因。

六、临时解决:停用出问题的 Snippet

为了先恢复线上访问,我第一步是停用这个 Snippet。

路径是:

WordPress 后台 → Code Snippets → All Snippets → 完美替代 16 条 Ad Inserter 规则的 PHP 代码 → Deactivate

停用后,旧文章恢复正常。

这一步很重要,因为在线上环境排查问题时,优先级最高的是先恢复用户访问,而不是马上改代码。

七、第一次修复尝试:顶部加 return 保护,但不够理想

我一开始尝试在 Snippet 顶部加一段防重复加载保护:

PHP
if (
    defined('SW_DESC_ADS_SNIPPET_LOADED') ||
    function_exists('custom_desc_and_ads_inserter') ||
    function_exists('custom_in_category_tree')
) {
    return;
}

define('SW_DESC_ADS_SNIPPET_LOADED', true);

这个思路是:

如果函数已经存在,就直接 return,避免重复声明。

但实际测试后发现,旧文章虽然不再稳定报同样的错误,但文章底部的推荐/咨询区块没有正常显示。

原因也很明显:

这个 Snippet 最后是通过下面这行直接输出内容的:

PHP
echo custom_desc_and_ads_inserter();

如果顶部提前 return,后面的输出逻辑也可能被跳过。

所以这种写法不够适合当前这个 Snippet。

八、最终修复:给函数声明加 function_exists 保护

更稳妥的方式,是不要在 Snippet 顶部直接 return,而是给每个自定义函数声明加 function_exists() 保护。

原来的主函数是:

PHP
function custom_desc_and_ads_inserter() {
    // 原来的函数内容
}

修改为:

PHP
if (!function_exists('custom_desc_and_ads_inserter')) {
  function custom_desc_and_ads_inserter() {
      // 原来的函数内容
  }
}

辅助函数原来是:

PHP
function custom_in_category_tree($cat_slug) {
    // 原来的函数内容
}

修改为:

PHP
if (!function_exists('custom_in_category_tree')) {
  function custom_in_category_tree($cat_slug) {
      // 原来的函数内容
  }
}

这样处理后,即使 WPCode 在某些请求中重复加载了同一个 Snippet,也不会再次声明已经存在的函数。

同时,代码末尾的输出逻辑仍然可以保留:

PHP
echo custom_desc_and_ads_inserter();

这比顶部直接 return 更适合这个 Snippet 的结构。

九、重新启用 Snippet 并测试

修改完成后,我重新启用了这个 Snippet。

然后分别测试:

旧文章页面是否正常打开;

底部推荐/咨询区块是否正常显示;

新文章页面是否正常打开;

新文章底部区块是否正常显示。

测试结果:

旧文章正常打开;

旧文章底部区块正常显示;

新文章正常打开;

新文章底部区块正常显示;

PHP-FPM 日志中没有新的 Fatal error。

【图7:旧文章页面恢复正常】

【图7:旧文章页面恢复正常】
【图8:文章底部推荐/咨询区块正常显示】
【图8:文章底部推荐/咨询区块正常显示】

十、完成 Yoast SEO 首次配置

确认致命错误修复后,我继续完成 Yoast SEO 的首次配置。

Yoast SEO 的首次配置主要包括以下几项:

SEO 数据优化;

现场代表;

社交个人资料;

偏好设置;

完成配置。

在“现场代表”这一步,我选择了“个人”。

【图9:Yoast SEO 现场代表设置】
【图9:Yoast SEO 现场代表设置】

社交个人资料这一步,我暂时没有补充,后续可以再完善。

【图10:Yoast SEO 社交个人资料设置】
【图10:Yoast SEO 社交个人资料设置】

偏好设置中,我没有订阅邮件,也选择不共享站点数据。

【图11:Yoast SEO 偏好设置】
【图11:Yoast SEO 偏好设置】

最后,Yoast SEO 显示配置完成。

【图12:Yoast SEO 首次配置完成】
【图12:Yoast SEO 首次配置完成】

十一、检查 Yoast SEO 仪表盘和 Alert center

配置完成后,我进入 Yoast SEO 仪表盘。

中间有一些 Yoast SEO Premium、Site Kit、SEO Task list 的推广提示,这些都不是必须处理的内容。

真正需要看的,是 Alert center。

Alert center 显示:

问题:0;

通知:0。

【图13:Yoast SEO Alert center 显示问题 0】
【图13:Yoast SEO Alert center 显示问题 0】

这说明 Yoast 当前没有检测到严重 SEO 配置问题。

十二、验证 XML Sitemap 和 robots.txt

安装 SEO 插件后,最重要的基础验证之一是 XML Sitemap。

打开:

Plaintext
https://www.shuijingwanwq.com/sitemap_index.xml

页面可以正常显示 Yoast SEO 生成的 sitemap index。

【图14:Yoast SEO XML Sitemap 正常生成】
【图14:Yoast SEO XML Sitemap 正常生成】

然后继续检查 robots.txt:

Plaintext
https://www.shuijingwanwq.com/robots.txt

内容中可以看到:

Plaintext
Sitemap: https://www.shuijingwanwq.com/sitemap_index.xml
【图15:robots.txt 中正确声明 sitemap 地址】
【图15:robots.txt 中正确声明 sitemap 地址】

这说明搜索引擎可以通过 robots.txt 找到 Yoast 生成的 XML Sitemap。

十三、最后清理缓存

完成配置和修复后,我通过 W3 Total Cache 清空了所有缓存。

路径是:

WordPress 后台顶部黑色工具栏 → 性能 → 清空所有缓存

【图16:W3 Total Cache 清空所有缓存】
【图16:W3 Total Cache 清空所有缓存】

清理缓存后,再次验证前台页面,确认旧文章、新文章、底部区块和 Yoast SEO 都正常。

十四、这次排查得到的结论

这次问题表面上看像是:

启用 Yoast SEO 后,旧文章打不开。

但最终排查下来,真正原因是:

WPCode 中的 PHP Snippet 重复声明了 custom_desc_and_ads_inserter() 函数,导致 PHP Fatal error。

Yoast SEO 只是让这个隐藏问题暴露出来,并不是根因。

比较稳妥的处理方式是:

不要急着卸载 Yoast;

先停用可疑 Snippet,确认页面是否恢复;

查看 PHP-FPM 日志,找到真正的 Fatal error;

对自定义 PHP 函数加 function_exists() 防重复保护;

重新启用 Snippet,并验证前台页面和 PHP 日志;

最后清理缓存。

十五、以后写 WPCode Snippet 需要注意什么?

这次问题也提醒我,以后在 WPCode 中写 PHP Snippet 时,最好养成几个习惯。

第一,自定义函数尽量加唯一前缀。

比如不要写太通用的函数名:

PHP
function custom_desc_and_ads_inserter() {
}

更好的方式是使用更明确的前缀:

PHP
function shuijingwan_custom_desc_and_ads_inserter() {
}

第二,函数声明前加 function_exists() 判断。

例如:

PHP
if (!function_exists('shuijingwan_custom_desc_and_ads_inserter')) {
  function shuijingwan_custom_desc_and_ads_inserter() {
      // ...
  }
}

第三,线上排查插件冲突时,不要只看表面现象。

这次如果只看现象,很容易误以为 Yoast SEO 有问题。

但日志里的关键错误并不在 Yoast 插件目录,而是在 WPCode 的 Snippet 执行器中。

所以 WordPress 出现致命错误时,PHP 日志比后台页面提示更有价值。

结语

这次重新安装 Yoast SEO 的过程,比预期多花了一些时间。

但结果是好的:

Yoast SEO 免费版已经正常启用;

首次配置完成;

XML Sitemap 正常生成;

robots.txt 正常声明 sitemap;

旧文章打不开的问题已经修复;

WPCode Snippet 的底部推荐/咨询区块也恢复显示;

PHP-FPM 日志中没有新的 Fatal error。

对一个运行多年的 WordPress 博客来说,重新启用 SEO 插件、恢复旧数据、兼容历史文章和现有自定义代码,本来就容易遇到各种隐藏问题。

这次排查也算是一次很典型的 WordPress 插件冲突处理案例:不要只看哪个插件刚刚启用,而是要通过日志找到真正报错的代码位置。

WordPress主题切换导致Bing流量下降实录(进行中):一次站点结构变更的SEO复盘

WordPress 网站维护、性能优化与博客运营咨询

本站已持续运营超过 10 年,累计发布 1000+ 篇原创技术文章,长期实践 WordPress 网站建设、CDN / Cloudflare 配置、缓存优化、Google SEO、广告变现和多语言网站运营。

如果你的 WordPress 网站遇到访问慢、缓存异常、插件冲突、广告不显示、SEO 基础结构混乱、CDN 配置不确定等问题,可以联系我做一次远程技术排查。

适合以下用户:
✅ 个人博客站长
✅ WordPress 网站运营者
✅ 独立开发者与内容创作者
✅ SaaS 产品官网运营团队
✅ 希望优化网站速度与稳定性的站点

服务内容:
✅ WordPress 速度优化
✅ Cloudflare / CDN / 缓存配置排查
✅ 插件冲突与页面异常排查
✅ AdSense 广告显示问题排查
✅ SEO 基础结构检查
✅ 博客运营与商业化咨询

如需了解方案或交流相关问题,请直接联系我,并注明:WordPress 维护咨询

联系方式:
Telegram:@shuijingwan
微信:13980074657
邮箱:shuijingwanwq@gmail.com

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理