这篇收四个不成体系但都实际遇到过的问题:两个故障、两个改造。每个都保留当时的现象、定位过程和解法。

插件把 CPU 吃满

某天站点卡到打不开,进服务器看 top,两个核的 CPU 全是满的,占用进程全是 php-fpm。

进不去后台,只能从文件系统下手:到 /www/wwwroot/imsxx.com/wp-content/plugins,把可疑插件的文件夹改名,WordPress 找不到目录就无法加载它,相当于变相停用。

站点恢复之后再看,罪魁是某个带「文章标签内链」功能的插件。它每次渲染文章都要扫描全文做替换,文章一多就把 PHP 进程占满。从后台关掉这个功能后,占用回到正常水平。

这个套路在没有后台权限时很好用:改目录名 = 停用插件,比进数据库改配置快,也比直接删掉安全。确认是哪个插件之后再决定是关功能还是卸载。

发布文章时无限加载

点「发布」之后转圈不停,最后白屏报错,但文章其实已经发出去了。

排查顺序是「先排除插件,再怀疑自己写的代码」:

  1. 关闭所有插件,确认发布恢复正常
  2. 逐个启用插件,每启用一个就试一次发布
  3. 启用 Easy WP SMTP 之后问题复现

但把 Easy WP SMTP 装到一个全新环境里测试,发布完全正常——说明不是插件本身的问题,而是我在它上面加的代码。

翻了很久才想起来,之前给邮件通知做过「美化」,往邮件模板里塞了一段自定义 HTML。这段代码挂在邮件插件里,而邮件插件又会在发布文章时被触发,代码写得不够干净,每次调用都把 post.php 的进程拖死。浏览器那边看到的就是一直转圈。

F12 里 post.php 返回 0,也印证了这一点:请求被异常中断,但文章数据已经写库了。

解法有两个:删掉美化代码,或者优化它。我选了前者——WordPress 自带的邮件通知确实简陋,但为了好看牺牲发布流程不值得。

教训:给插件加自定义代码时,要确认它挂在哪个钩子上。挂在 publish_post 这类高频钩子上的代码,一次性能问题就能拖垮整个后台。

主题的双 H1

WordBook 主题把站点 logo 写成了 <h1>,文章标题也是 <h1>,一页出现两个 H1,对 SEO 不友好。

在「外观 → 主题编辑器」打开 header.php,把 logo 部分的 h1 改成 div:

PHP
<div class="logo">
  <a href="<?php bloginfo('url'); ?>" title="<?php bloginfo('name'); ?>">
    <?php if (get_theme_mod('ds_logo')): ?>
      <img src="<?php echo get_theme_mod('ds_logo'); ?>" alt="">
    <?php endif; ?>
    <?php if (get_theme_mod('ds_logo_dark')): ?>
      <img src="<?php echo get_theme_mod('ds_logo_dark'); ?>" alt="">
    <?php endif; ?>
    <?php if (get_theme_mod('ds_site_name')): ?>
      <b><?php echo get_theme_mod('ds_site_name') ?></b>
    <?php endif; ?>
  </a>
</div>

改完样式可能受影响,因为原来的 h1 选择器不再命中。如果 logo 位置或字号变了,去 style.css 里把 .logo h1 换成 .logo 即可。

原则是:一个页面只保留一个 H1,且它应该是文章标题。首页可以是站点名,但文章页必须是文章标题。

在所有文章的第二段后插入广告

WordPress 没有原生的「段落级」钩子,只能用 the_content 过滤器处理字符串。

把下面这段加到主题的 functions.php 末尾:

PHP
function insert_after_first_paragraph($content) {
    if (!is_single()) return $content;

    $parts = explode('</p>', $content);
    if (count($parts) > 1) {
        $ad = '<div class="inserted-content centered-content">这里换成你的广告代码或链接</div>';
        $parts[1] .= $ad;
        $content = implode('</p>', $parts);
    }
    return $content;
}
add_filter('the_content', 'insert_after_first_paragraph');

function add_custom_styles() {
    echo '<style>
        .centered-content {
            text-align: center;
            margin: 20px 0;
        }
    </style>';
}
add_action('wp_head', 'add_custom_styles');

几个细节:

  • 按 </p> 分割比按换行分割稳,因为 WordPress 输出的段落一定以 </p> 闭合
  • $parts[1] 就是第一段(数组从 0 开始),在它后面追加内容等于插在第二段之前
  • is_single() 限制只对文章页生效,首页和页面不受影响
  • 改了没生效,先清缓存,再确认主题是否另有 functions.php 的自定义加载机制

如果站点用了页面缓存,插入的广告在缓存生成时就固定了,换广告代码要顺手清一次缓存。

相关内容

一台 2C4G VPS 上用 1Panel(LEMP + Docker)跑多个 WordPress,优化后后台变慢并出现 EdgeOne 524。本文按时间线复盘:如何从“缓存/超时”误区切换到“容器环回 + Docker 出网被 iptables FORWARD 掐死”的根因定位,最终用 host-gateway + iptables 持久化完成修复,并给出可复制的检查清单。

WordPress运维1Panel

一台 2 核 4G 的 VPS 承载 4 个 WordPress:从 PHP-FPM 的 ondemand 改造、MySQLTuner 诊断、MariaDB 参数收敛,到缓存分层、端口暴露检查和 swap 兜底。

VPSWordPress1Panel

搜索

开始搜索
↑↓
↵
ESC
Ctrl K快捷键