网站开发

WordPress 调试三板斧:出问题时的定位方法

WordPress 出问题,真正的难点往往不是「怎么修」,而是「到底是哪出问题了」。

页面慢——是插件、是主题、还是数据库?白屏——是哪行代码?某个功能不生效——是钩子没触发还是优先级不对?

凭猜是最慢的方式。这篇讲三个工具,能覆盖绝大多数定位需求。

第一板斧:WP_DEBUG(让错误说出来)

WordPress 默认隐藏所有 PHP 错误。白屏的本质就是「报错了但你看不到」。

开启方式:编辑 wp-config.php:

define( 'WP_DEBUG', true );          // 开启调试模式
define( 'WP_DEBUG_LOG', true );      // 错误写到日志文件
define( 'WP_DEBUG_DISPLAY', false ); // 不在页面显示(生产环境用 false)

三个参数的区别

  • WP_DEBUG:总开关
  • WP_DEBUG_LOG:错误写入 /wp-content/debug.log。生产环境关键是这个
  • WP_DEBUG_DISPLAY:错误直接显示在页面上。生产环境必须设 false,否则访客能看到你的服务器路径、数据库结构——严重的信息泄露

正确的生产环境配置

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );

这样:你看得见(在日志里),访客看不见。很多教程教你全设 false,那样出问题你什么线索都没有。

看日志

tail -f /wp-content/debug.log

实时看最新错误。重现问题的时候开着它,错误会一条条刷出来。

注意:debug.log 是公开可访问的路径(你的域名/wp-content/debug.log)。用完记得删除或者禁止访问——它会暴露你的服务器结构。

nginx 禁止访问:

location ~* /debug\.log$ {
    deny all;
}

更细的控制

define( 'WP_DEBUG', true );
define( 'SCRIPT_DEBUG', true );   // 加载未压缩的 JS/CSS,方便前端调试
define( 'SAVEQUERIES', true );    // 记录所有 SQL 查询(会很慢,只临时开)

第二板斧:Query Monitor(看出是谁在捣乱)

这是个免费插件,WordPress 开发调试的第一利器。装上之后,后台和前台顶部会多一个工具栏。

它能看什么

面板 用途
Queries 本次页面所有 SQL 查询、耗时、是哪个插件发起的
Slow Queries 慢查询单独列出来
Hooks & Actions 本次请求触发的所有钩子,以及挂在上面的函数
PHP Errors notices、warnings、deprecated 信息
Template 当前页面用的是哪个模板文件,以及模板层级
Request 当前请求的查询变量
HTTP API Calls 有没有外部请求(比如插件调用第三方 API)

几个高频用法

1. 找出页面慢的原因

看 Queries 面板的总耗时和查询次数。点开按耗时排序,最慢的那条 SQL 会显示「Caller」(调用者)——直接告诉你哪个插件/主题文件发起的。

2. 确认模板文件

想改某个页面的样式但不知道改哪个文件?看 Template 面板,它会列出当前用的模板文件和完整的层级链。

3. 找出隐藏的 PHP 错误

页面看着正常,但 PHP Errors 面板有红色警告——这些往往就是某些功能异常的原因。很多「莫名其妙的问题」都是被忽略的 PHP notice 引起的。

4. 查看钩子

想知道某个钩子上挂了哪些函数?Hooks & Actions 面板列得清清楚楚,包括优先级。

使用技巧

Query Monitor 会增加开销,排查完可以停用(或者只在需要时启用)。

它还有个实用功能:可以设置「只对管理员显示」,这样不影响访客。

第三板斧:二分法隔离(定位是哪个插件)

前两个工具告诉你「出了什么错」,但要确定「是谁导致的」,最快的方法是二分排除。

场景:某个功能不正常,怀疑是插件冲突

  1. 禁用一半插件,看问题是否消失
  2. 消失了 → 问题在被禁用的那一半里;没消失 → 在还在启用的那一半里
  3. 对有问题的那一半重复操作

20 个插件,4-5 次就能定位到具体的那一个。比一个个禁用快得多。

更快的方法:健康检查插件

装 Health Check & Troubleshooting(WordPress 官方出的)。它有个「故障排除模式」:

  • 启用后,只有你(管理员)看到的是「所有插件禁用 + 默认主题」的状态
  • 访客看到的还是正常网站

这个设计很妙——你能在线上安全地排查,不影响真实访客。不用在半夜停用插件测试。

在排除模式下逐个启用插件,看问题什么时候复现。

组合使用:一个真实的排查流程

假设:网站某个页面打开特别慢,其他页面正常。

第 1 步:确认是不是数据库问题

装 Query Monitor,打开那个慢页面,看 Queries 面板:

  • 查询次数特别多(几百次)→ 某个插件在做 N+1 查询(循环里查数据库)
  • 单条查询特别慢(> 1 秒)→ 索引问题,看 Slow Queries
  • 查询都很快 → 瓶颈不在数据库,可能是外部 API 请求

第 2 步:看 HTTP API Calls

Query Monitor 的 HTTP API Calls 面板会显示外部请求。如果有个请求耗时 3 秒,那页面慢的原因就是它——比如某个插件在页面加载时同步调用天气 API、汇率 API、或者某个统计服务。

这类问题非常常见,而且特别隐蔽——因为你的服务器很快,慢的是别人的接口。

第 3 步:定位到具体插件

Query Monitor 的每个查询都标了 Caller,直接告诉你文件路径。看路径里的插件名就知道是谁。

第 4 步:验证

用故障排除模式停用那个插件,再看页面速度。确认了就处理:

  • 换成同类但更轻量的插件
  • 如果必须用,看它有没有缓存设置
  • 实在不行,把插件的调用改成异步(页面加载完再用 Ajax 请求)

几个额外的调试技巧

临时打印变量

// 打印到页面
echo '<pre>';
print_r( $变量 );
echo '</pre>';
die();   // 停在这,只看这个变量

// 或者写到日志
error_log( print_r( $变量, true ) );

error_log() 配合 WP_DEBUG_LOG,输出到 debug.log。比 echo 更干净,不会破坏页面布局。

查看当前请求的所有信息

global $wp_query;
error_log( print_r( $wp_query->query_vars, true ) );

调试「为什么这个页面显示的是这些内容」时特别有用——看查询变量就知道 WordPress 以为你在请求什么。

检查钩子是否触发

add_action( '某个钩子', function() {
    error_log( '钩子触发了!' );
}, 1 );

在日志里搜这句话,就知道钩子有没有执行。

查看 SQL 执行计划

global $wpdb;
$wpdb->query( 'EXPLAIN ' . $your_sql );
error_log( print_r( $wpdb->last_result, true ) );

调试的几条原则

1. 一次只改一处

同时改三处,问题解决了你也不知道是哪处解决的;问题没解决你也不知道该查哪处。

2. 先记录再修改

改之前先确认「现在的具体表现是什么」——截图、复制错误信息、记录复现步骤。否则改了几轮之后你会忘记最初的问题是什么。

3. 排除法优于猜测

「我觉得应该是缓存问题」然后去清缓存——这是猜测。「停用所有插件后问题消失,说明是插件导致的」——这是排除。后者快得多。

4. 用日志而不是记忆

排查过程中发现的信息记下来。特别是复现步骤——「怎么操作能让问题出现」。没有稳定的复现步骤,你就无法验证修复是否成功。

最后

这三个工具的学习成本都很低:WP_DEBUG 是改三行配置,Query Monitor 是装个插件,二分法是个思路。

但它们能把「不知道问题在哪」变成「知道问题在哪」——而这一步,占了整个修复过程 80% 的时间。

很多人修 WordPress 的问题修一整天,不是因为难修,是因为一直在猜。用对工具,同样的可能二十分钟就解决了。