调试工具(Xdebug)
Xdebug 是 PHP 生态中最强大、最全面的调试和分析工具。它提供了断点调试、堆栈跟踪、代码覆盖率分析、性能分析(Profiling)等功能,是 PHP 开发者排查 Bug 和优化性能不可或缺的工具。本节将详细介绍 Xdebug 的安装、配置以及在 VS Code 和 PhpStorm 中的调试集成。
前置知识
- 已完成 PHP 的基本安装(参考 Unix/macOS 安装)
- 了解 IDE 的基本配置(参考 IDE 与编辑器配置)
- 了解 HTTP 协议和 PHP 请求生命周期
基础概念
Xdebug 的功能模块
Xdebug 是一个多功能工具,其功能可以分为以下几个模块:
| 功能 | 说明 | 适用场景 |
|---|---|---|
| 远程调试(Debug) | 断点调试、变量检查、单步执行 | Bug 排查 |
| 开发辅助(Develop) | 堆栈跟踪增强、错误报告美化 | 日常开发 |
| 性能分析(Profile) | 生成性能分析报告 | 性能优化 |
| 代码覆盖(Coverage) | 统计测试代码覆盖率 | 单元测试 |
| 垃圾回收分析(GC) | 分析垃圾回收行为 | 内存优化 |
Xdebug 3.x 版本
Xdebug 3.x 是当前的主版本,对配置进行了大幅简化。Xdebug 2.x 已不再维护。本节所有配置均基于 Xdebug 3.x。如果你的环境还是 Xdebug 2.x,请参考 迁移指南 进行升级。
Xdebug 模式
Xdebug 3.x 引入了模式概念,通过 xdebug.mode 配置项控制启用哪些功能:
; Xdebug 3.x 模式配置
; 可以同时启用多个模式,用逗号分隔
; 仅启用远程调试
xdebug.mode = debug
; 启用调试 + 开发辅助
xdebug.mode = debug,develop
; 启用调试 + 性能分析
xdebug.mode = debug,profile
; 启用所有功能(不建议,性能开销大)
xdebug.mode = debug,develop,profile,coverage,gcstats安装 Xdebug
通过 PECL 安装(推荐)
# 安装最新版 Xdebug
sudo pecl install xdebug
# macOS(Homebrew)
pecl install xdebug
# 验证安装
php -m | grep xdebug
# 查看版本
php -r "echo phpversion('xdebug');"通过包管理器安装
# Ubuntu/Debian
sudo apt install php8.2-xdebug -y
# CentOS/RHEL (Remi)
sudo dnf install php82-php-xdebug -y
# 验证安装
php -m | grep xdebug编译安装
# 下载 Xdebug 源码
curl -LO https://xdebug.org/files/xdebug-3.3.1.tgz
tar -zxf xdebug-3.3.1.tgz
cd xdebug-3.3.1
# 编译安装
phpize
./configure --enable-xdebug
make
sudo make install
# 验证
php -m | grep xdebug在 Docker 中安装
FROM php:8.2-fpm-alpine
# 安装编译依赖
RUN apk add --no-cache $PHPIZE_DEPS
# 安装 Xdebug(仅开发环境)
RUN pecl install xdebug \
&& docker-php-ext-enable xdebug
# 开发环境配置
RUN { \
echo 'xdebug.mode = debug,develop'; \
echo 'xdebug.start_with_request = yes'; \
echo 'xdebug.client_host = host.docker.internal'; \
echo 'xdebug.client_port = 9003'; \
echo 'xdebug.discover_client_host = true'; \
echo 'xdebug.log = /tmp/xdebug.log'; \
} > /usr/local/etc/php/conf.d/xdebug.ini
# 清理编译依赖
RUN apk del $PHPIZE_DEPS详细配置
php.ini 配置详解
; ============== Xdebug 核心配置 ==============
; 启用的模式(debug=远程调试, develop=开发辅助, profile=性能分析)
xdebug.mode = debug,develop
; 是否在每个请求中自动启动调试
; yes — 自动启动(开发环境推荐)
; no — 手动触发(通过浏览器插件或 GET/POST 参数)
; trigger — 通过 XDEBUG_TRIGGER 触发
xdebug.start_with_request = yes
; ============== 远程调试配置 ==============
; 调试客户端(IDE)的主机
; localhost — 本地开发
; host.docker.internal — Docker 环境
xdebug.client_host = localhost
; 调试客户端端口(Xdebug 3.x 默认 9003)
xdebug.client_port = 9003
; 自动发现客户端 IP(适用于 Docker/虚拟机)
xdebug.discover_client_host = true
; IDE 密钥(用于区分不同的 IDE 会话)
; xdebug.idekey = VSCODE
; ============== 开发辅助配置 ==============
; 堆栈跟踪中显示的函数参数数量(0 表示不显示)
xdebug.var_display_max_children = 128
; 数组/对象中显示的最大元素数
xdebug.var_display_max_data = 1024
; 字符串显示的最大长度
xdebug.var_display_max_depth = 3
; ============== 性能分析配置 ==============
; 当 profile 模式启用时
; xdebug.output_dir = /tmp
; xdebug.profiler_output_name = cachegrind.out.%p
; ============== 日志配置 ==============
; Xdebug 自身日志(排查连接问题时使用)
xdebug.log = /tmp/xdebug.log
xdebug.log_level = 3
; ============== 其他配置 ==============
; 最大嵌套层数
xdebug.max_nesting_level = 512
; 触发器值(当 start_with_request = trigger 时)
xdebug.trigger_value = XDEBUG_TRIGGER开发环境完整配置
; /etc/php/8.2/conf.d/xdebug-dev.ini
; 开发环境 Xdebug 配置(启用所有开发辅助功能)
zend_extension = xdebug.so
xdebug.mode = debug,develop
xdebug.start_with_request = yes
xdebug.client_host = localhost
xdebug.client_port = 9003
xdebug.discover_client_host = true
; 堆栈跟踪增强
xdebug.var_display_max_children = 128
xdebug.var_display_max_data = 1024
xdebug.var_display_max_depth = 3
; 开发辅助美化
xdebug.cli_color = 1
; 日志(排查问题时开启)
;xdebug.log = /tmp/xdebug.log
;xdebug.log_level = 3生产环境配置
生产环境禁用 Xdebug
Xdebug 会显著降低 PHP 性能(通常 15%~30%)。生产环境应完全禁用 Xdebug。
; 生产环境:完全禁用 Xdebug
; 方法 1:删除或注释掉 zend_extension 行
; 方法 2:设置空模式
; xdebug.mode = off
; 如果需要保留 Xdebug 但仅启用开发辅助(无调试开销):
;xdebug.mode = off验证安装
基本验证
# 检查 Xdebug 是否已加载
php -m | grep xdebug
# 查看 Xdebug 版本和配置
php -i | grep xdebug
# 使用 php --ri 查看详细信息
php --ri xdebug输出示例:
xdebug
xdebug support => enabled
Version => 3.3.1
Support Xdebug on => enabled, if loaded via php.ini
...
xdebug.mode => debug,develop
xdebug.start_with_request => yes
xdebug.client_port => 9003
xdebug.client_host => localhost创建测试脚本
<?php
declare(strict_types=1);
// 测试 Xdebug 堆栈跟踪增强
function levelOne(): void
{
levelTwo();
}
function levelTwo(): void
{
levelThree();
}
function levelThree(): void
{
// 触发一个警告
trigger_error('Xdebug 堆栈跟踪测试', E_USER_WARNING);
}
levelOne();# 运行测试脚本
php test-xdebug.php如果 Xdebug 已正确安装并配置了 develop 模式,你将看到一个美化的堆栈跟踪,包含参数值和源代码位置。
远程调试
VS Code 调试配置
步骤 1:安装 PHP Debug 扩展
在 VS Code 扩展面板中搜索 "PHP Debug"(作者 Felix Becker),点击安装。
步骤 2:创建 launch.json
// .vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Listen for Xdebug",
"type": "php",
"request": "launch",
"port": 9003
},
{
"name": "Launch current script in CLI",
"type": "php",
"request": "launch",
"program": "${file}",
"cwd": "${fileDirname}",
"port": 9003,
"runtimeArgs": [
"-dxdebug.start_with_request=yes"
]
},
{
"name": "Launch built-in web server",
"type": "php",
"request": "launch",
"runtimeArgs": [
"-dxdebug.start_with_request=yes",
"-S",
"localhost:8080",
"-t",
"public"
],
"port": 9003,
"serverReadyAction": {
"pattern": "Development Server \\(http://localhost:([0-9]+)\\) started",
"uriFormat": "http://localhost:%s",
"action": "openExternally"
}
}
]
}步骤 3:开始调试
- 在代码中设置断点(点击行号左侧)
- 按
F5或点击调试面板中的 "Start Debugging" - 选择 "Listen for Xdebug"
- 在浏览器中访问你的应用,VS Code 将在断点处暂停
PhpStorm 调试配置
步骤 1:配置 PHP 解释器中的 Xdebug
File -> Settings -> Languages & Frameworks -> PHP- 确认 CLI Interpreter 旁显示 "Xdebug" 标识
- 点击 "..." -> "Xdebug" 标签,确认端口为 9003
步骤 2:配置调试服务器
File -> Settings -> Languages & Frameworks -> PHP -> Servers- 添加服务器:名称、主机、端口、调试器选择 "Xdebug"
- 配置路径映射(本地路径 -> 服务器路径)
步骤 3:开始调试
- 在代码中设置断点
- 点击调试按钮(电话图标)开始监听
- 在浏览器中安装 Xdebug Helper 插件并启用调试
- 访问应用页面,PhpStorm 将在断点处暂停
调试操作指南
断点调试中的常用操作:
| 操作 | VS Code | PhpStorm | 说明 |
|---|---|---|---|
| 设置断点 | 点击行号左侧 | 点击行号左侧 | 红点表示断点 |
| 继续执行 | F5 | F9 | 运行到下一个断点 |
| 单步跳过 | F10 | F8 | 执行当前行,不进入函数 |
| 单步进入 | F11 | F7 | 进入函数内部 |
| 单步跳出 | Shift+F11 | Shift+F8 | 从当前函数跳出 |
| 停止调试 | Shift+F5 | Cmd+F2 | 终止调试会话 |
| 查看变量 | 左侧面板 | 左侧面板 | 实时查看变量值 |
| 条件断点 | 右键断点 | 右键断点 | 设置条件表达式 |
| 表达式求值 | 调试控制台 | Alt+F8 | 在运行时计算表达式 |
性能分析(Profiler)
启用性能分析
; 临时启用性能分析模式
xdebug.mode = debug,profile
; 性能分析输出目录
xdebug.output_dir = /tmp
; 性能分析文件名格式
xdebug.profiler_output_name = cachegrind.out.%p.%H
; 触发方式
xdebug.start_with_request = trigger使用触发器进行性能分析
# 通过 GET 参数触发
curl "http://example.com/api/products?XDEBUG_TRIGGER=1"
# 通过 Cookie 触发
curl -b "XDEBUG_TRIGGER=1" http://example.com/api/products
# 分析完成后,输出文件位于:
# /tmp/cachegrind.out.<pid>.<hash>分析性能报告
# 使用 QCacheGrind 工具打开分析报告
# macOS
brew install qcachegrind
qcachegrind /tmp/cachegrind.out.12345.abcde
# Linux
sudo apt install kcachegrind
kcachegrind /tmp/cachegrind.out.12345.abcdeQCacheGrind 的关键指标解读:
- Inclusive Time:函数自身执行时间 + 调用的子函数时间
- Self Time:函数自身执行时间(不含子函数)
- Call Count:函数被调用次数
- Memory:函数使用的内存
PHP 代码中的性能分析
<?php
declare(strict_types=1);
// 在代码中手动控制 Xdebug 性能分析
function analyzeApiCall(): void
{
// 开始性能分析
xdebug_start_function_monitor();
xdebug_start_trace('/tmp/api-trace');
// 执行要分析的代码
$result = fetchApiData();
$processed = processResult($result);
// 停止性能分析
xdebug_stop_function_monitor();
xdebug_stop_trace();
}
// 使用 CPU 时间差测量
$startTime = hrtime(true);
// 执行代码
doSomeHeavyWork();
$endTime = hrtime(true);
$durationMs = ($endTime - $startTime) / 1_000_000;
echo "执行时间: {$durationMs}ms\n";堆栈跟踪
增强的错误显示
Xdebug 的 develop 模式会美化 PHP 的错误信息,显示完整的堆栈跟踪和变量值:
<?php
declare(strict_types=1);
function calculateTotal(array $items): float
{
$total = 0.0;
foreach ($items as $item) {
// 故意制造一个错误(除以零)
$total += $item['price'] / $item['quantity'];
}
return $total;
}
$items = [
['name' => 'Apple', 'price' => 5.99, 'quantity' => 3],
['name' => 'Banana', 'price' => 2.99, 'quantity' => 0], // quantity = 0!
];
calculateTotal($items);没有 Xdebug 时的错误输出:
Warning: Division by zero in /path/to/script.php on line 9有 Xdebug 时的错误输出(develop 模式):
( ! ) Warning: Division by zero in /path/to/script.php on line 9
Call Stack
# Time Memory Function Location
1 0.0001 360784 {main}( ) .../script.php:0
2 0.0002 361328 calculateTotal( ... ) .../script.php:19配置堆栈跟踪显示
; 堆栈跟踪中显示的参数数量
xdebug.var_display_max_children = 128
; 字符串显示的最大长度
xdebug.var_display_max_data = 1024
; 数组/对象嵌套深度
xdebug.var_display_max_depth = 3
; CLI 彩色输出
xdebug.cli_color = 1注意事项
常见问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
| IDE 无法接收到调试连接 | 端口不匹配或防火墙阻止 | 确认 client_port 与 IDE 配置一致 |
| 调试断点不生效 | 路径映射不正确 | 配置 pathMappings 或 PhpStorm 的 Server 映射 |
| 页面加载缓慢 | Xdebug 开销导致 | 开发完成时关闭 Xdebug |
| "Cannot find Xdebug" | 未正确加载扩展 | 检查 zend_extension=xdebug.so 是否在 php.ini 中 |
| Docker 中无法调试 | 容器网络隔离 | 使用 host.docker.internal 和 discover_client_host |
性能影响
Xdebug 对 PHP 性能的影响:
| 模式 | 性能影响 | 建议 |
|---|---|---|
off | 无 | 生产环境必须关闭 |
develop | 约 5% | 可接受,但生产环境仍建议关闭 |
debug | 约 15%~30% | 仅开发环境启用 |
profile | 约 50%+ | 仅需要性能分析时临时启用 |
切记关闭生产环境的 Xdebug
Xdebug 即使在 off 模式下,也会有一定的启动开销。生产环境应完全禁用(注释掉 zend_extension 行)。
最佳实践
开发环境配置:开发环境启用
debug,develop模式,获得完整的调试和开发辅助功能。生产环境禁用:生产环境完全禁用 Xdebug,避免性能损失。
使用浏览器插件:安装 Xdebug Helper 浏览器扩展(Chrome/Firefox),可以一键开启/关闭调试,避免每次修改配置。
配置路径映射:远程调试或 Docker 环境中,务必正确配置路径映射,否则断点无法命中。
利用条件断点:在循环内部调试时,使用条件断点避免每次迭代都暂停,大幅提升调试效率。
查看 Xdebug 日志:当调试连接失败时,开启
xdebug.log查看详细日志,定位连接问题。定期升级:Xdebug 会持续修复 bug 和优化性能,定期升级到最新版本。