PHP断点调试([wsl2|docker]+swoole+xdebug+phpstorm)
本文针对 Hyperf 框架基于 Swoole 的常驻内存特性,结合 WSL2 环境下源码编译的 PHP 8.1、Xdebug 3.2.2 调试组件及 Docker 容器化部署场景,梳理了一套完整的远程断点调试配置方案。内容涵盖 PHP 源码编译与扩展安装、Xdebug 核心参数配置、PhpStorm 调试环境关联、Docker 端口映射设置,以及 Hyperf 框架调试适配要点(如关闭守护进程、
目录
前沿
在 PHP 开发领域,dd()等传统调试方式曾长期占据主流,但在面对 Hyperf 这类基于 Swoole 的高性能协程框架时,其局限性逐渐凸显 —— 异步任务的执行流程难以追踪、常驻内存进程的状态无法实时观测,调试效率大打折扣。而远程断点调试作为更高效的调试手段,能直接在代码执行节点暂停、查看变量与调用栈,成为解决这类问题的最优解。
然而,远程断点调试的配置涉及多环境联动:WSL2 系统的 PHP 源码编译与扩展依赖、Xdebug 3.x 的参数适配、PhpStorm 与容器 / 本地服务的端口映射、Hyperf 框架的调试模式适配,任何一个环节配置不当都会导致调试失败。网上现有教程多零散片面,缺乏针对 WSL2+Docker+Hyperf 组合场景的完整指引。
基于此,本文整合实战经验,从环境搭建到调试验证,逐步拆解全流程配置要点,旨在为开发者提供一套可直接复用的远程断点调试方案,助力提升 Hyperf 框架下的开发与排障效率。
环境
- 系统:wsl2(为什么不再win里面安装PHP,因为最新的swoole没有dll)
- PHP:8.1.31
- Swoole:5.1.5
- Xdebug:3.2.2
前置条件的安装
- swoole(pecl安装方式)
sudo pecl install --configureoptions 'enable-sockets="no" enable-openssl="yes" enable-http2="yes" enable-mysqlnd="yes" enable-swoole-json="no" enable-swoole-curl="yes" enable-cares="yes" enable-swoole-pgsql="yes"' swoole-5.1.5
swoole.use_shortname='Off' 这些设置就参考swoole官方文档
没有用hyperf的也不需要安装swoole
- xdebug(pecl安装方式)
sudo pecl install xdebug-3.2.2
xdebug配置
可以通过 “php --ini” 找到你的xdebug.ini
; ==================== Xdebug 3.2.2 完整配置 ====================
; 扩展加载
zend_extension=xdebug.so
[xdebug]
; 模式设置(可多个模式用逗号分隔)
; debug - 调试模式
; develop - 开发功能(包括堆栈跟踪)
; coverage - 代码覆盖率
; gcstats - 垃圾回收统计
; profile - 性能分析
; trace - 函数跟踪
xdebug.mode =
; 自动发现客户端主机(WSL2 推荐)
xdebug.discover_client_host=0
xdebug.client_host = 127.0.0.1
; 客户端端口
xdebug.client_port=9001
; 对于 Swoole 常驻内存应用,建议使用 yes 而不是 trigger
xdebug.start_with_request=trigger
; xdebug.trigger_value=hantaohuang 这里一定要注释掉的,不能填,填了就只支持一个项目,不填就是支持传进来的任何值
xdebug.max_nesting_level = 512
; 日志配置(调试时启用)
xdebug.log=/tmp/xdebug.log
xdebug.log_level=7
; 其他配置 tail -f /tmp/xdebug3 查看日志
xdebug.output_dir=/tmp/xdebug3
xdebug.use_compression=1
xdebug.connect_timeout_ms=200
tips:
- xdebug.mode 你可以统一的都设置为空或者off(laravel项目需要修改“php artisan serve”命令,看下方文档,如果不想修改命令则需要固定设置为develop,否则调试不会成功)
- xdebug.log=/tmp/xdebug.log 没配置好之前可能会频繁的看日志
- php --ri xdebug 可以看到你的实际配置
- xdebug.client_port=9001 需要和后面的phpstrom配置一致
- xdebug.client_host=host.docker.internal (docker需要换成这个地址)
phpstorm
-
服务器配置

-
phpstorm中xdebug端口

-
调试配置入口设置

-
解释器配置

-
运行/调试配置(hyperf)

-
运行/调试配置(laravel)

-
环境变量的参数
- PHP_IDE_CONFIG="serverName=ums" 和你配置的服务器一致即可
- XDEBUG_TRIGGER=umsService 随意取,每个项目不一样即可
-
配置好了

-
docker的额外配置
-
镜像中需要暴露端口

-
端口绑定

-
镜像
- registry.cn-chengdu.aliyuncs.com/mz-andy/php-nginx-alpine:8.1-hyperf-debug
- registry.cn-chengdu.aliyuncs.com/mz-andy/php-nginx-alpine:8.1-laravel-debug
- 按照下方的修改“php artisan serve”命令,则可以不使用php-nginx-alpine:8.1-laravel-debug镜像
- (我准备了阿里云的镜像,不想搞环境的直接上docker)实际测下来docker的方式没有直接在环境中跑php来得快,启动时还是有卡顿不流程
- 有需要dockerfile的,留下邮箱
-
配置好了
照样显示连接成功,docker ps之后你会发现多了一个实例
-
# 框架相关的
-
hyperf(mineadmin)
-
scan_cacheable
package-ordering\config\config.php scan_cacheable=>true (因为hyperf断点调试的初始只能是代理类) -
daemonize
package-ordering\config\autoload\server.php settings[ .... Constant::OPTION_DAEMONIZE => false, ] # true时:Xdebug 无法附着到前台进程,断点调试会失效 -
worker_num
package-ordering\config\autoload\server.php settings[ .... Constant::OPTION_WORKER_NUM => env('APP_DEBUG') ? 1 : swoole_cpu_num(), ] worker_num让它等于1就行了,也就是APP_DEBUG=true -
mineadmin 不要使用"php watch -C"
- 如果watch本身接受debug就会卡住不动,这就是为啥有的人加入debug之后启动在文件监听那一块停止不动了的原因
- 修改了代码之后,需要像java一样重新启动。或者自己再取研究一下热启动
-
-
laravel
- 暂时没有发现需要特殊的地方
# 浏览器插件
-
chrome
-
firefox
- 实测好像也不需要这个
解决laravel无法动态设置xdebug.mode的问题
- 原因是xdebug3的环境变量设置失败(这个没找到原因),但是可以通过-dxdebug.mode=debug的方式动态设置
[docker://registry.cn-chengdu.aliyuncs.com/mz-andy/php-nginx-alpine:8.1-hyperf-debug/]:php -dxdebug.mode=debug -dxdebug.client_port=9001 -dxdebug.client_host=host.docker.internal /opt/project/artisan serve --port=21981 --host=0.0.0.0
php artisan serve 里面执行的是 php -S .....把 外层的 -dxdebug.mode=debug -dxdebug.client_port=9001 -dxdebug.client_host=host.docker.internal 参数给丢掉了,xdebug3的环境变量设置又是失败的,所以只能改 php artisan serve 这个命令
期待官方修改 php artisan serve 增加 -dxdebug.mode 的动态设置方式
-
增加命令
- 创建一个命令 app\Console\MyServeCommand.php 并在app\Console\Kernel.php 中注册该命令
-
<?php namespace App\Console; use Illuminate\Foundation\Console\ServeCommand; use Symfony\Component\Process\PhpExecutableFinder; class MyServeCommand extends ServeCommand { /** * The console command name. * * @var string */ protected $name = 'serve'; /** * Get the full server command. * * @return array */ protected function serverCommand() { $server = file_exists(base_path('server.php')) ? base_path('server.php') : __DIR__ . '/../resources/server.php'; $mode = ini_get('xdebug.mode'); return array_merge_recursive( [ (new PhpExecutableFinder)->find(false) ], $mode ? [ '-dxdebug.mode=' . $mode ] : [], [ '-S', $this->host() . ':' . $this->port(), $server ] ); } }根据laravel版本不同,自行更改(点到父级的serverCommand方法)
-
根目录新增一个serve.php
-
<?php $publicPath = getcwd(); $uri = urldecode( parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) ?? '' ); // This file allows us to emulate Apache's "mod_rewrite" functionality from the // built-in PHP web server. This provides a convenient way to test a Laravel // application without having installed a "real" web server software here. if ($uri !== '/' && file_exists($publicPath.$uri)) { return false; } require_once $publicPath.'/index.php';
-
# tips
- 先打断点再启动
- 重启时端口被占用,再多重启一次
- php -S 可以启用tp,yii等其他框架,php artisan serve --port=8000 也只是对php -S的封装
- php --ini
- php --ri xdebug
- tail -f /tmp/xdebug3
- 关掉opcache
# 文档
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐

所有评论(0)