xdebug 3 默认端口改为9003是为了避免与zend server、docker compose或charles等工具默认占用的9000端口冲突,实现调试通道专用化;若被占,需同步修改php.ini的xdebug.client_port、ide监听端口及cli调试配置,并确保dbgp proxy中ide连9001、xdebug连9003。

为什么 Xdebug 3 默认用 9003,而不是 9000?
Xdebug 3 把调试端口从旧版的 9000 改为 9003,不是为了“高大上”,而是为了避免和一些系统服务(比如某些版本的 Zend Server、旧版 Docker Compose 默认映射)或本地代理工具(如 Charles、Fiddler 的监听端口)冲突。它本质是向后兼容的妥协:保留 9000 给其他用途,把调试专用通道明确划给 9003。
但问题来了——你本地可能已有另一个服务占了 9003,或者你的 IDE(比如老版本 PhpStorm)仍默认监听 9000,这时断点就完全不触发,连日志里都看不到连接尝试。
解决思路很直接:要么换掉占用端口的服务,要么让 Xdebug 和 IDE 同步改用其他端口。别硬扛默认值。
如何安全地修改 Xdebug 3 的 client_port?
改端口本身很简单,但必须同步改三处,缺一不可:
-
xdebug.client_port在php.ini中设为你想用的新端口(比如9004) - IDE 的调试监听端口必须一致:PhpStorm 是 Run → Start Listening for PHP Debug Connections 后在设置里确认;VS Code 的
launch.json中"port": 9004 - 如果用了 Xdebug CLI 调试(比如
php -dxdebug.mode=debug -dxdebug.start_with_request=yes script.php),也要确保本地有服务在监听那个端口,否则会超时失败
注意:xdebug.client_port 只控制 Xdebug 主动发起连接的目标端口,它不开启监听——监听是 IDE 或 DBGp Proxy 干的事。很多人卡在这儿,以为改了这个参数 IDE 就自动切换端口,其实不会。
9003 被占用了,怎么快速定位是谁?
别靠猜。终端执行这行命令就能看到谁在用 9003:
lsof -i :9003
常见占用者包括:
-
phpstorm进程(说明你之前启过监听但没关干净) -
code或Code Helper(VS Code 的调试子进程) -
docker-proxy(Docker 容器映射了该端口) -
nginx或apache(极少见,但某些自定义配置可能绑定了)
杀掉对应 PID 即可:kill -9 <pid></pid>。如果是 Docker 占用,检查 docker-compose.yml 里的 ports: 段,临时注释掉 - "9003:9003" 这类映射。
用 DBGp Proxy 时,9001 和 9003 到底谁连谁?
这是最容易配反的地方。DBGp Proxy 是个中间人,它开两个端口:
-
9001:IDE 主动连它(注册自己,带idekey),所以你的 PhpStorm/VS Code 的调试配置里,host填的是 Proxy 地址,port必须是9001 -
9003:Xdebug 主动连它(发调试数据),所以php.ini里xdebug.client_port = 9003,且服务器要能访问到 Proxy 的9003端口
换句话说:IDE → Proxy:9001,Xdebug → Proxy:9003。两个端口不能写反,也不能全写成 9003。Proxy 启动命令类似:dbgpProxy --host=0.0.0.0:9001 --port=9003。
端口冲突常发生在 Proxy 部署在远程服务器时——你只开了 9001 的防火墙入站,却忘了 9003 是 Xdebug 主动连过来的,需要出站放行(或云平台安全组允许该端口入站)。











