一般PHP开发环境是以本地环境为主的,少数人会用测试服务器做开发环境。当项目切换到正式环境时,有时为了测试线上某功能,或者修复bug时,以前都是通过写日志或者打印调试(如:var_dump),如果项目访问量很少,测试目标数据不多时,用这种方式调试问题不大。但是如果测试的数据比较多,那调试起来很繁琐,不断切换位置打印或写日志调试,很浪费时间。

遇到的问题

要实现PHP远程打断点调试,首先需要解决最大的问题是服务器怎么访问本地,其次的是线上环境的配置和本地的配置。 先解决服务器和本地通讯的问题。 目前我所知道的有三种通讯方式,一种是与服务器建立隧道,一种是使用内网穿透,比如frp,另外一种是使用异地组网方式。隧道强力推荐,其次是内网穿透,异地组网成本比较贵。

隧道连接

一般ssl连接服务器软件都可以方便的建立隧道,以FinalShell软件为例,

ssl隧道

在终端设置这里配置连接服务器信息并成功连接之后,就可以直接建立隧道了,类型为远程,监听端口指的是本地需要接收xdebug调试的端口,目标端口和目标地址针对线上的,xdebug配置信息:

xdebug.remote_host=127.0.0.1
xdebug.remote_port=9000

意思是说当服务器接收到9000端口的数据,直接转发到本地的9000端口,可以在服务器运行netstat -ltn命令查看端口是否正常监听。

端口

此处需要注意的是本地要先连接服务器,这样才能转发成功。如果线上项目是运行在docker上,xdebug.remote_host要填写宿主机的ip

内网穿透

内网穿透需要支持tcp转发,可以使用第三方的,也可以自己搭建。 免费我这边介绍飞鸽,注册之后开通免费隧道,注意选择tcp协议,就可以看到隧道基本信息。

隧道信息

其中free.vipnps.vip:39776表示当请求该地址时将数据通过tcp协议传送到本地的9000端口上,如果要配置xdebug,就配置:

xdebug.remote_host=free.vipnps.vip
xdebug.remote_port=39776

然后本地运行客户端就可以进行远程调试了。 如果自己搭建内网穿透也很容易,去githubfrp的项目地址,下载地址 根据操作系统选择编译好的文件,压缩包里面有客户端和服务端的配置文件,服务端可以放在测试服务器,也可以放在正式服务器。可以结合Supervisor运行服务端,Supervisor的配置文件参考如下:

[program:frp]
command=/root/frps/frp_0.35.1_linux_amd64/frps -c frps.ini
directory=/root/frps/frp_0.35.1_linux_amd64/
autorestart=true
startsecs=3
startretries=3
stdout_logfile=/www/server/panel/plugin/supervisor/log/frp.out.log
stderr_logfile=/www/server/panel/plugin/supervisor/log/frp.err.log
stdout_logfile_maxbytes=2MB
stderr_logfile_maxbytes=2MB
user=root
priority=999
numprocs=1
process_name=%(program_name)s_%(process_num)02d

frps.ini的配置文件可以直接用默认,有一个是bind_port的参数,这个是服务端监听frp客户端的端口,该端口需要对外开放。 本地客户端frpc.ini配置文件参考如下:

[common]
server_addr = frp服务端所在ip
server_port = frps.ini的bind_port配置项,默认为7000

[xdebug]
type = tcp
local_ip = 127.0.0.1 # 本地ip
local_port = 9000 # 本地监听端口
remote_port = 9000 # 远程服务器监听端口,远程9000端口转发到本地9000端口

xdebug配置参考如下:

xdebug.remote_host=frp服务端所在ip
xdebug.remote_port=本地frpc.ini设置的remote_port端口

运行正常以后就可以远程调试了。

异地组网

异地组网我推荐使用蒲公英,测试服务器或正式服务器运行客户端,本地环境再另外运行客户端,此时服务器和本地就建立了虚拟局域网,同时也分配了局域网ipxdebug配置如下:

xdebug.remote_host=本地虚拟局域网ip
xdebug.remote_port=本地xdebug监听端口,比如9000 

操作步骤与内网穿透差不多,这里就不多介绍了。

Xdebug配置

打开phpstorm,需要配置几个参数:

配置

这里配置本地需要监听的端口。

配置

这里配置xdebug配置的key、线上地址和本地监听端口。

配置

然后在Servers配置项里设置线上地址和项目目录的映射。 配置完之后可以进行Debug配置:

配置

如果选择PHP Remote Debug形式调试的话,可以结合xdebug helper浏览器扩展配合调试,这种相对比PHP Web Page调试方式方便很多。

配置

线上xdebug配置参考如下:

;开启xdebug支持远程调试
xdebug.remote_enable=1
;远程调试的主机,一般都是docker宿主机器,本地调试就是本机,ip可以通过`docker inspect 容器名获得`
xdebug.remote_host=127.0.0.1
;远程调试机器的端口,一般是9000,和后面讲到的phpStorm里面保持一致
xdebug.remote_port=9000
;idekey 对接调试的密钥,和后面phpStorm里面的务必保持一致
xdebug.idekey=PHPSTORM
;自动触发调试,可以将这个值设为1;
;xdebug.remote_autostart=1
;更多参数介绍请参见这里 https://xdebug.org/docs/all_settings
;xdebug.remote_connect_back=1
xdebug.remote_handler=dbgp
;xdebug.remote_mode=req
;xdebug.max_nesting_level=250
;xdebug.remote_log='/www/wwwlogs/xdebug_docker.log'

总结

远程调试建议使用隧道方式,因为这种是最快的,也是最稳定的,如果项目是运行在docker上,xdebug.remote_host就不能设置127.0.0.1了,需要设置宿主机的ip,运行docker inspect命令可查看宿主机的ip