Connection refused 是 Xdebug 主动连接 IDE 失败,根本原因是目标 IP:Port 无进程监听;需通过 xdebug.log 确认是否发起连接,再检查 client_host/client_port 配置、IDE 是否监听、防火墙/Docker 网络等。

Connection refused 不是 PHP 文件打不开,而是 Xdebug 尝试连 IDE 时根本没人应答。先确认它是不是真在连、连谁、为什么连不上。
怎么看 Xdebug 到底有没有发起连接?
别猜,直接看日志——这是唯一可靠入口:
在 php.ini 或 xdebug.ini 里加两行:xdebug.log_level=10xdebug.log=/tmp/xdebug.log(确保 PHP 进程有写权限,比如 sudo chmod 777 /tmp/xdebug)
重启 PHP 服务后访问带 ?XDEBUG_SESSION_START=1 的页面,再打开日志文件:
• 如果压根没出现 Connecting to configured address,说明 Xdebug 根本没启动调试——检查 xdebug.mode=debug 和 xdebug.start_with_request=trigger 是否生效
• 如果看到 Connecting to 127.0.0.1:9003 紧接着 Could not connect to client,说明它动了,只是连不上
IDE 监听地址和端口对不对?
Connection refused 的本质是:TCP 包发到了目标 IP:Port,但那个端口上没进程在 accept()。
验证方法非常直接:
• 在 IDE 启动调试监听后,Linux 执行 ss -tln | grep :9003,Windows 执行 netstat -an | findstr :9003,没输出就等于没监听
• VS Code 用户重点核对 launch.json 里的 port 是否为 9003,且必须和 xdebug.client_port 完全一致
• PhpStorm 默认只监听 127.0.0.1:9003;如果你用 Docker,xdebug.client_host 设成 localhost 就会解析成容器自己的 127.0.0.1——此时得填宿主机网关(如 172.17.0.1)或启用 host.docker.internal
防火墙、Docker 网络、SELinux 拦没拦?
即使 IDE 监听了,中间层也可能把包掐掉:
• 本地防火墙:sudo ufw status(Ubuntu)或 sudo firewall-cmd --state(CentOS),确认 9003 入站放行
• 云服务器安全组:检查是否允许你开发机 IP 的 TCP 9003 入向规则
• Docker 场景:docker run 必须带 -p 9003:9003,且容器内 xdebug.client_host 要指向宿主机(不是 localhost)
• Mac M1/M2 用户注意:host.docker.internal 在某些 Docker Desktop 版本下不自动解析,可临时改用 10.0.2.2 或宿主机真实 IP
• SELinux(CentOS/RHEL):sudo setsebool -P httpd_can_network_connect 1,否则 Apache 子进程连不出去
xdebug.client_host 填错是最常见坑
很多人以为 client_host 是“让谁来连我”,其实相反:它是 Xdebug 主动连出去的目标地址。
所以:
• PHP 和 IDE 在同一台机器(本地开发)→ xdebug.client_host=127.0.0.1
• PHP 在远程服务器或 Docker 容器 → xdebug.client_host 必须填你本地电脑的 IP(比如 192.168.1.100),不能填 localhost 或 127.0.0.1
• WSL2 下,xdebug.client_host 填 Windows 主机 IP,并确保 Windows 防火墙放行 9003
• xdebug.discover_client_host=0 必须显式关闭,避免 DNS 解析干扰导致地址错乱
立即学习“PHP免费学习笔记(深入)”;
Xdebug 日志里反复出现Could not connect to client 却没进一步报错,大概率是 client_host 或 client_port 错了,或者 IDE 根本没开监听——这两点比调超时参数重要十倍。



















