欢迎转载,但请在开头或结尾注明原文出处【blog.chaosjohn.com】
前言
在前文 php 调试指南(Xdebug版) 开头,笔者吹了一句 ”吃透本文,没有人将比你更懂 Php Xdebug 调试“。没想到打脸来的如此之快,这才过了三四天,我发现今天的我比写前文时的我,更懂 了。
关于 PhpStorm 2020.3 和 Xdebug 3
在前文中,笔者用的还是 PhpStorm 2020.2.4
,所以结合 Xdebug 3.0.0
在使用 Web Server Debug Validation
进行 调试环境验证 时,提示类似 Xdebug port is invalid
的报错,分析是 不兼容 3.0.0 版本 导致的。所以降级成了 Xdebug 2.9.8
才顺利写完了文章。
写完前文的第二天,PhpStorm 2020.3就发布了,新增
- 对
PHP 8
的支持 - 对
Xdebug 3
的支持
在重新用 PHPBrew
安装 PHP 8
+ Xdebug 3.0.0
环境并且用 Nginx
+ php-fpm
部署起来后,Web Server Debug Validation
成功验证。
关于 Web Server Debug Validation
功能
笔者在前文写完后,在升级 PhpStorm 2020.3
之前,笔者重新安装了 PHP 7.4.13
+ Xdebug 3.0.0
环境,在忽略 验证报错
的情况下直接开启调试,是完全没有任何问题的。所以,该功能只是 验证调试环境
,在调试之前仅作参考,不影响实际调试。
关于 远程调试
笔者在写前文关于 远程调试 的几节时,参考了网上很多文章,看似吃透了,其实不然,原因有这样几点:
- 网上很多文章的作者写文时也如同笔者写前文时一样,对原理一知半解,导致很多讲解其实不完善或者南辕北辙。正确的做法:研读
JetBrains
/VSCode
/Xdebug
的官方文档,去理解它的原理。- Configure Xdebug—PhpStorm PhpStorm官方:配置 Xdebug
- Remote debugging via SSH tunnel—PhpStorm PhpStorm官方:通过SSH隧道进行远程调试
- Multiuser debugging via Xdebug proxies—PhpStorm PhpStorm官方:通过 Xdebug 代理进行多人调试
- PHP Debug Adapter for Visual Studio Code VSCode PHP Debug 插件主页文档
- Step Debugging Xdeubg官方:单步调试
- Documentation - all settings Xdebug官方:所有配置项
- Upgrading from Xdebug 2 to 3 Xdebug官方:从Xdebug 2 升级到 Xdebug 3
- 笔者写前文时搭建的
远程调试环境
不完善- 本机 和 远程服务器 都是
macOS
- 本机 和 远程服务器 都在
局域网内
- 本机 和 远程服务器 都是
IDE
结合 Xdebug
调试的原理
IDE(本身或利用插件)
打开本地的9000
端口并进行监听(Xdebug 2.X 默认为9000
,Xdebug 3.X 默认为9003
,但均可修改)IDE(本身或利用插件)
做好路径映射(path mapping
),即本地在IDE中打开的项目目录与远程服务器上的项目目录做一一映射,例如- macOS 本地:
/Users/chaos/Work/php/demos/debug/
- Linux 服务器:
/home/chaos/Work/php/demos/debug/
- macOS 本地:
- 本地向服务器发送请求时带上
Cookie: XDEBUG_SESSION=IDEKEY
- 服务器接受到请求时,经历了
Nginx
->php-fpm
后到达Xdebug
,Xdebug
检测到XDEBUG_SESSION
的cookie
,认为这条请求是带着调试目的
来的,同时挂起PHP解释器
进一步处理请求 - 然后
Xdebug
从php.ini
中获取目标地址或从$_SERVER
里获取到请求的来源地址(比如223.104.148.182
)作为目标地址,然后就向目标地址的9000
端口发起建立调试连接
- 本地的
IDE(本身或利用插件)
发现监听的9000
端口有调试连接
建立,判断一下XDEBUG_SESSION
是否为自己预设的IDE key
- 如果不是预设
IDE key
,通过9000
端口上的调试连接
告诉服务器的Xdebug
,“不归我管,我不处理”,然后双方协商一下断连接 - 如果是预设
IDE key
,同时发现本地打了断点或者本地设置了"stopOnEntry": true
(VSCode) /Break at first line in PHP scripts
(PhpStorm),则告诉服务器的Xdebug
,“收到,调试准备就绪”,然后双方协商一下进入调试状态
- 如果不是预设
真实环境下 远程调试 的 陷阱
聪明的小伙伴可能已经发现上述 调试流程
里存在的一个 陷阱
:即服务器要向本地请求建立 调试连接
,但问题是,现在所有的 家用/企业 网络环境下,所谓的 本地
都在上级路由器的 NAT
下,根本就没有暴露在公网的 IP地址
,所以 本地
的 9000
端口对于服务器来说,是不可达的,想要访问,做梦!
填坑 陷阱
笔者重新模拟了真实的调试环境,即 本地
为 macOS
,远程服务器
选了两台 Linux
,一台是笔者在公司搭建的 物理机,另一台是公司购买的阿里云 云主机。
填坑的最终目的,是要使得 本地
的 9000
端口暴露给服务器,让其直接可达。
这里分:
- 本地和远程服务器同处一个局域网内,例如,都加入同一个
VPN
网络,本地通过VPN
分配给服务器的私网IP
访问服务器,服务器的Xdebug
解析到的来源地址则也是通过VPN
分配给本地的私网IP
,直接可达。 - 路由器本身从
ISP(宽带运营商)
通过PPPoE 拨号
获取到了公网IP
,然后路由器上通过端口映射
或DMZ 模式
,将本地的9000
端口,映射到路由器的9000
端口,这样服务器也可通过公网IP:9000
访问到本地的9000
端口。(该方式最推荐,但是在国内可行度不高,因为国内IP地址池
即将枯竭,所以很难从运营商处申请到公网IP
) - 其他环境只能借助 移花接木大法:借助
SSH 反向隧道
,在本地和服务器之间建立一条TCP通道
,将本地的9000
端口映射到服务器的9000
端口。这样的话,服务器上的Xdebug
访问localhost:9000
就等于访问到了IDE本地
的9000
端口。(借用 JetBrains 官方文档里的一副插图)
在这里,笔者将前两种环境归纳为 回程网络直接可达
,否则则为 回程网络不可直达
。
PhpStorm
的特殊配置
在分别罗列远程调试的具体参数配置之前,笔者还得额外将 PhpStorm
的特殊配置单独拎出来阐述一下。
PhpStorm
调试的 目标服务器,以 Server
的存在进行配置,具体位于 偏好设置
的 Languages and Frameworks | PHP | Servers
下。详见 JetBrains 官方文档,原文是这样的:
PhpStorm
调试的特殊配置:在远程服务器上的 php-fpm
配置文件里添加这两行:
clear_env = no
env["PHP_IDE_CONFIG"] = "serverName=UbuntuServer"
这里 UbuntuServer
是自定义的服务器名称,自行更改。
然后在 PhpStorm
偏好设置的 Languages and Frameworks | PHP | Servers
添加一个 Server
name
填UbuntuServer
Host
和Port
笔者亲测可填任意合法值,PhpStorm
不校验,所以笔者都填写了0
值Debugger
选择Xdebug
- 勾选上
Use path mappings
,并且设置好本地文件目录路径
和服务器文件目录路径
的映射(比如笔者本地的/Users/chaos/Work/php/demos/debug/
与服务器的/home/chaos/Work/php/demos/debug/
)
VSCode
的配置
只需要比本地调试多配置一个 路径映射
,即 pathMappings
键值对,附上 launch.json
文件内容:
{
"version": "0.2.0",
"configurations": [
{
"name": "Listen for XDebug",
"type": "php",
"request": "launch",
"port": 9000,
// "stopOnEntry": true,
"pathMappings": {
"/home/chaos/Work/php/demos/debug/": "${workspaceRoot}/",
}
},
{
"name": "Launch currently open script",
"type": "php",
"request": "launch",
"program": "${file}",
"cwd": "${fileDirname}",
"port": 9000
}
]
}
这里的 "/home/chaos/Work/php/demos/debug/": "${workspaceRoot}/"
是 "/home/chaos/Work/php/demos/debug/": "/Users/chaos/Work/php/demos/debug/"
的简化形式,${workspaceRoot}
则为 VSCode
中打开的 项目根目录
。
服务器的 php.ini
在不同情况下的配置
情况一:回程网络直接可达
- Xdebug 2.X
[xdebug]
xdebug.remote_enable=1
xdebug.remote_connect_back=1
- Xdebug 3.X
[xdebug]
xdebug.mode=debug
xdebug.discover_client_host=true
xdebug.port=9000
情况二:回程网络不可直达
先用 SSH 隧道
反向将本地的 9000
端口映射到服务器的 9000
端口上
ssh -g -N -R 9000:127.0.0.1:9000 user@server
- Xdebug 2.X (Method A)
[xdebug]
xdebug.remote_enable=1
xdebug.remote_host=127.0.0.1
- Xdebug 2.X (Method B)
[xdebug]
xdebug.remote_enable=1
xdebug.remote_connect_back=1
xdebug.remote_addr_header="HTTP_X_XDEBUG_REMOTE_ADDR"
- Xdebug 3.X (Method A)
[xdebug]
xdebug.mode=debug
xdebug.port=9000
xdebug.client_host=127.0.0.1
- Xdebug 3.X (Method B)
[xdebug]
xdebug.mode=debug
xdebug.port=9000
xdebug.discover_client_host=true
xdebug.client_discovery_header="HTTP_X_XDEBUG_REMOTE_ADDR"
其中 Xdebug 2.X (Method B)
与 Xdebug 3.X (Method B)
还有些许不同:
Xdebug 2.X (Method B)
如果按配置规则没找到请求发起地址,它不会降级使用127.0.0.1/localhost
作为请求发起地址Xdebug 3.X (Method B)
如果按配置规则没找到请求发起地址,它会降级使用127.0.0.1/localhost
作为请求发起地址
多人调试 - DBGp
先附上参考文档
- Multiuser debugging via Xdebug proxies PhpStorm官方:通过 DBGp 代理进行多人调试
- DBGp Proxy Tool Xdebug官方
这块我不仅会略过,我还会狠狠的吐槽一下。先来看一下上述 "Multiuser debugging via Xdebug proxies" 这篇文里的一张插图
看似很美妙是不是,在笔者下载了 dbgpProxy
并且反复实验后,发现这个工具真的是神坑。
笔者在那台阿里云上运行 ./dbgpProxy -i 0.0.0.0:9001 -s 127.0.0.1:9000
后,从本地的 PhpStorm
带着自定义IDE key
"PS"
发起调试请求,结果 dbgpProxy
日志打印 Connecting to 112.3.2.42:9000
,而笔者所在的本地宽带并没有公网IP,112.3.2.42
这个IP是多层 NAT
之前的IP,肯定访问不进来,只能上 SSH 隧道方案
。
那这个 dbgpProxy
的意义何在呢?笔者在网上找到了 Xdebug
的作者 Derick Rethans
(他同时设计了 DBGp 协议
)的一篇文章 - Debugging with multiple users,在文中,他描绘了 DBDp
的使用场景:
大致解释一下:
- 你的路由器得从ISP处获取到公网IP
- 在你的路由器上运行
dbgpProxy
- 路由器下所有人的的
IDE
的DBGp Proxy 配置
的Host
填写路由器网关,即路由器内网地址
到这里,你可以发现,搭建 DBGp调试环境
非常苛刻,结合 公网IP
和 路由器运行 dbgpProxy
这两点看,只有 软路由
可以满足,因为 dbgpProxy
的二进制可执行文件只有 Windows
/ macOS
/ Linux x86-64
版本。所以大部分人/公司 可以洗洗睡了。
结语
为了写这两篇文,笔者是翻来覆去做了很多实验,还整理了很多知识点,打了很多草稿(真正意义上的纸质草稿),最后附上最满意的一张草稿。
希望读者们能有所收获,感谢阅读!
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!