hyperf使用Xdebug调试断点

1. 前言#

昨天在 hyperf 交流群里有道友问 hyperf 框架能否使用 Xdebug 进行断点调试,在与群友沟通了下,并将自己的配置发给对方看后,最终也没能解决。
因为之前写 go 的原因,个人比较喜欢使用 debug 对代码进行断点调试,目前写 php 也经常使用 Xdebug 进行调试,但是目前公司项目都是使用常规的 PHP-FPM 模式,swoole 模式下应该不太一样。
所以今天我打算一探究竟,hyperf 框架是否能够使用 Xdebug。

2. 环境#

今天讲的是两种环境下使用 Xdebug 进行断点调试,分别为 本地环境直接调试 和 使用 docker 环境调试

2.1 本地环境#

os: Mac OS
php: 8.1.21
swoole: 5.0.3
xdebug: 3.2.2 

2.2 docker 环境#

os: apline
php: 8.1.25
swoole: 5.0.3
xdebug: 3.1.5 

2.3 注意事项#

1. Xdebug 的大版本不同,配置也相对不同,本次环境中使用的是 3.x 版本,如果有使用 2.x 版本的朋友请注意修改对应 php.ini 中 Xdebug 配置

2. swoole 版本小于 5.x 的无法支持 Xdebug 如使用低于 5.x 版本会报错:Fatal error: Uncaught ErrorException: Swoole\Server::start(): Using Xdebug in coroutines is extremely dangerous, please notice that it may lead to coredump!
如图:

3. 本地环境使用 Xdebug#

3.1 在 php.ini 配置 Xdebug#

具体的配置如下:

[Xdebug]
zend_extension="xdebug.so"
# xdebug模式
xdebug.mode=debug

# 请求开始时自动开启
xdebug.start_with_request=yes

# client_host client_port 是 xdebug v3.x 中才有的选项
xdebug.client_host=127.0.0.1 

# 此处为监听端口,配置集成开发环境时需要(重要)
xdebug.client_port=9003
xdebug.collect_return=true

# 此处搭配的 PHPSTORM,配置 PHPSTORM 时需要
xdebug.idekey=PHPSTORM 

#   下面配置项,是在 xdebug v2.x 下常用的配置项,不要在 xdebug v3.x 下使用
##   xdebug.remote_host=127.0.0.1
##   xdebug.remote_handle=dbgp
##   xdebug.remote_enable=on

3.2.1 phpstorm 中增加【hyperf 运行脚本】 - 与 3.2.2 选其中一种即可#

点击【运行 / 调试配置】-> 左上角 + 号 -> PHP 脚本

  • 名称:hyperf-xdebug (可任意编写)
  • 文件:/Users/liang/www/github.com/liangguifeng/hyperf-test/bin/hyperf.php (对应调试 hyperf 项目的下 bin/hyperf.php 文件)
  • 实参:start (hyperf 的启动参数)
  • 解释器:/usr/local/Cellar/php@8.1/8.1.21/bin/php(8.1.21) (自己的 php 路径,需要提前在 phpstorm 中配置号)

如图:

调试【hyperf 运行脚本】

3.2.2 phpstorm 中配置 debug 监听 - 与 3.2.1 选其中一种即可#

phpstorm 开启监听 debug

3.4 phpstorm 中增加断点#

因为 hyperf 框架中默认开启了 AOP,所以会产生代理类文件,php 会解析代理类文件,而非直接解析对应 controller,如图:

正确断点,应该找到对应的代理类文件,进行 debug 断点,代理类文件默认存储在
项目目录/runtime/container/proxy/
如图:

3.5 发起请求#

终端中请求,如图:

phpstorm 断点展示,如图:

4. docker 环境使用 Xdebug#

4.1 在 php.ini 配置 Xdebug#

具体的配置如下:

[Xdebug]
# xdebug模式
xdebug.mode=debug

# 请求开始时自动开启
xdebug.start_with_request=yes

# client_host client_port 是 xdebug v3.x 中才有的选项,`host.docker.internal` 是docker内部访问宿主机的host
xdebug.client_host=host.docker.internal

# 此处为监听端口,配置集成开发环境时需要(重要)
xdebug.client_port=9003
xdebug.collect_return=true

# 此处搭配的 PHPSTORM,配置 PHPSTORM 时需要
xdebug.idekey=PHPSTORM 

#   下面配置项,是在 xdebug v2.x 下常用的配置项,不要在 xdebug v3.x 下使用
##   xdebug.remote_host=127.0.0.1
##   xdebug.remote_handle=dbgp
##   xdebug.remote_enable=on

4.2 phpstorm 中配置 debug 监听 - 一定要先开启监听再启动 hyperf,否则无法断点#

phpstorm 开启监听 debug

4.3 docker 内部启动 hyperf 框架 - 一定要先开启监听再启动 hyperf,否则无法断点#

# 如果php.ini配置了Xdebug的配置,直接运行即可
php bin/hyperf.php start

# 如果没有配置,可用-d参数临时修改当前php脚本运行的ini配置
php -dxdebug.mode=debug -dxdebug.client_port=9003 -dxdebug.client_host=host.docker.internal /Users/liang/www/github.com/liangguifeng/hyperf-test/bin/hyperf.php start

因为我这里 docker 已经有了其他配置,所以我使用 -d 参数对配置进行临时修改

4.4 phpstorm 中增加断点#

因为 hyperf 框架中默认开启了 AOP,所以会产生代理类文件,php 会解析代理类文件,而非直接解析对应 controller,如图:

正确断点,应该找到对应的代理类文件,进行 debug 断点,代理类文件默认存储在
项目目录/runtime/container/proxy/
如图:

4.5 发起请求#

终端中请求,如图:

phpstorm 断点展示,如图:

4.6 其他方案 - 未成功,但是理论可行#

点击【运行 / 调试配置】-> 左上角 + 号 -> PHP 远程调试

配置如图:
服务器配置 (实际就是设置一个监听端口和目录映射):

配置好对应的 Xdebug key

理论上来说,当如下图点击调试【hyperf-xdebug-remote】的时候,会监听刚刚服务器配置的端口,docker 中通过 host.docker.internal + 端口号,应该可以访问到对应端口,所以理论上是可以成功 debug 的。
但是我执行 php bin/hyperf.php start 时,却卡主了,不会往下运行,也不纠结了,有一种方式就行,如果有知道原因的道友可以留言

5. 结语#

每个人都有自己习惯调试程序的方式,之前用 laravel 的时候 dd 习惯了,后面写了几年 go,开始习惯 debug 了,当然也有很多人喜欢用 var_dump,总之不管黑猫白猫,能抓老鼠就是好猫,debug 方式而已,大家根据喜好自行挑选。

本作品采用《CC 协议》,转载必须注明作者和本文链接
犯二青年
本帖由系统于 9个月前 自动加精
讨论数量: 4

感谢分享,👍🏻

1年前 评论

主要是为什么 swoole5+, php 还要要求 8.1+, 不是很友好,旧项目都没办法 debug 了,yasd 好像不是很兼容,调式的时候经常断开

1年前 评论
犯二青年 (楼主) 1年前

docker remote debug 可以参考这篇文章 segmentfault.com/a/119000002254244...

4个月前 评论