简介
- 工欲善其事必先利其器,很多PHPer多年来一直使用echo调试程序,其实还是蛮辛苦的,这篇文章将介绍如何通过XDebug完成断点调试的功能。
- XDebug 与IDE链接中会遇到很多莫名其妙的问题,这包括使用的PHP版本,使用的IDE版本,以及调试方式的不同,本文都会介绍,帮你迅速搭建XDebug调试开发环境。
- 这篇文章整理一个可以调试通畅的版本,并且展示如何进行简单的单步调试。
先简单说一下Xdebug 的原理
- 我只是文字描述一下,便于理解,
- 第一步,XDebug 是开发环境下的一个PHP模块,所以XDebug模块是安装到服务端的,安装配置好后XDebug 将监听
XDEBUG_SESSION_START={KEY}
这个get参数,{KEY} 是你设定好的(一般默认填写PHPSTORM) - 第二步,当XDebug接收到
XDEBUG_SESSION_START={KEY}
get请求,就会验证配置中的xdebug.idekey
是否和{KEY}相互匹配,如果匹配则进入第三步。 - 第三步,XDebug,向
xdebug.remote_host
配置的IP,xdebug.remote_port
的端口发送调试信息。 - 第四部,如果上面的接口接收到信息,就会发送断点信息,给XDebug,XDebug 则会中断PHP执行,并继续监听调试命令,如此反复完成调试。
- 简单了解XDebug 的原理对之后的配置还是很有帮助的。
安装XDebug
- 通过
pecl install xdebug && docker-php-ext-enable xdebug
命令安装即可。 - 安装成功后的提示:
+----------------------------------------------------------------------+
| |
| INSTALLATION INSTRUCTIONS |
| ========================= |
| |
| See https://xdebug.org/install.php#configure-php for instructions |
| on how to enable Xdebug for PHP. |
| |
| Documentation is available online as well: |
| - A list of all settings: https://xdebug.org/docs-settings.php |
| - A list of all functions: https://xdebug.org/docs-functions.php |
| - Profiling instructions: https://xdebug.org/docs-profiling2.php |
| - Remote debugging: https://xdebug.org/docs-debugger.php |
| |
| |
| NOTE: Please disregard the message |
| You should add "extension=xdebug.so" to php.ini |
| that is emitted by the PECL installer. This does not work for |
| Xdebug. |
| |
+----------------------------------------------------------------------+
配置php.ini 文件,开启XDebug扩展
-
php -i|grep -i xdebug
如果有信息弹出表示已经安装成功,直接重启即可。
安装后一般会创建
/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
此时就会开启XDebug了。(目录可能略有不同)-
此时 phpinfo() 的输出应该包含xdebug,看到信息表示配置成功了
配置XDebug配置文件
首先找到自己电脑的IP:
ifconfig |grep -i inet
我的是Mac,我的IP是192.168.1.164
这个后面配置时有用。可以通过命令 php -i |grep xdebug 找到配置文件位置。
编辑配置文件:
vim /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
(你的位置可能不一样不能完全照搬)
; 这个东西是默认存在的不可照抄,路径不要错,否则xdebug根本打不开
zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20180731/xdebug.so
xdebug.profiler_enable=on
xdebug.trace_output_dir="/usr/local/php/xdebug_trace"
xdebug.profiler_output_dir="/usr/local/php/xdebug_profiler"
xdebug.default_enable=0
xdebug.remote_enable=1
xdebug.remote_handler=dbgp
; 这个IP就是你链接XDebug IDE的IP不要搞错。
xdebug.remote_host=192.168.1.164
; 这个端口就是链接IDE是的端口,也就是PHP的服务器 `telnet 192.168.1.164 19001` 一定要能连接,当然现在不行因为还没有配置IDE。
xdebug.remote_port=19001
xdebug.remote_connect_back=0
xdebug.remote_autostart=1
; 这个是触发XDEBUG调试的KEY,为了先了解过程先不要修改。
xdebug.idekey=PHPSTORM
xdebug.remote_log=/usr/local/php/xdebug/remote.log
- 重启你的容器或者PHP,让配置生效,可以通过 phpinfo() 看一下
xdebug.idekey
的值什么的是否都正常,要保证和配置的一样否则就是出问题了,先要查清楚。 - 如果一切正常PHP端就不需要在碰了,但是注意一个前提就是PHP服务器上
ping xdebug.remote_host
中的配置值一定要通畅。
启动PHPStrom 的端口监听
- 打开PHPStrom
Preferences | Languages & Frameworks | PHP | Debug
- 注意下图红线部分,端口我们设置成
19001
,然后我们开启Debug Connections
点击第二个红线部分,让其保持Listening的状态,设置好后IDE就可以接受XDebug发过来的变量信息了。
-
我的是Mac 电脑,通过lsof -i:19001 测试一下监听端口是否已经启动。
配置PHPServers PHP服务器
- 打开PHPStrom
Preferences | Languages & Frameworks | PHP | Servers
-
点击小+号新增一个Servers,Name随便起一个,Host是Http的服务器,Port是Http服务器的端口,我的是7003根据实际情况填写即可,Debugger选择Xdebug。
配置IDE - 配置Php remote debug (PHP远程调试)
-
点击调试配置窗口,选择
Edit Configurations
-
点击配置的小加号,往下看选择
PHP Remote Debug
-
选择之前创建的Sever :
70030-laravel
,填写Chrome 的IDE key:PHPSTORM
。
测试通过PHPStorm 断点调试PHP
如果大家有兴趣还可以安装Chrome浏览器的
xdebug helper
,谷歌商店如果上不去可以通过我的网盘下载:链接: https://pan.baidu.com/s/15ocm6LGoG1Z-dtT-4iY-Ug 密码: egs2
这个插件实际上不是必须的,本文不做介绍。要注意如果你的PHP版本是7.0以上,推荐你的PHPStrom 是 2019.1 及其以上的版本,如果是用2018的版本肯能链接会出问题,这个要特别注意,我这里是PHPStrom 2019.2。
-
随便打开一段php 的代码添加断点:
-
接下来选择调试服务器,选择刚才创建的那个
PHPFPM-Docker-V5
-
之后确保 debug 处于监听状态,也就是那个小电话是联通的状态
-
全部配置好后应该是这个状态,参考下图。
-
此时Debug 调试窗口自动弹出,并且提示
Waiting for incoming connection with ide key 'PHPSTORM'
等待PHPSTORM标识的链接。
接下来就开始进行发送Debug信息了,返回到浏览器中,输入
http://localhost:7003/phpinfo.php?XDEBUG_SESSION_START=PHPSTORM
,如果不明白为何输入这个请参考文章开头的原理部分即可。-
如果程序运行正常会进入一个
假死
的状态,实际上程序并没有终端,而是在调试中,这时候回到PHPStrom中可以看到第一个断点前的数据变量。
-
点击 Next line 按钮可以看到代码光标下移,并且显示出第一个变量的值
如上全部,这里面要特别注意IP的配置,端口的配置和监听,另外千万不要忽视IDE的和PHP版本匹配我的PHP是7.3,运行在本地的Docker容器中,IDE是PHPStrom 2019.2
最后希望可以帮到你。
一些补充
- 如果服务器用的是阿里云或者腾讯云,可以通过VPN直接连接到服务器内网即可。
- 如果是内网服务器可以通过Nginx转发的方式实现,如下是配置文件参考:
vim /etc/nginx/nginx.conf
# 最外层,最后添加 stream 段落
stream {
include /etc/nginx/tcp.d/*.conf;
}
-
vim /etc/nginx/tcp.d
添加一个转发代理。
# 添加socket转发的代理
upstream socket_proxy {
hash $remote_addr consistent;
# 转发的目的地址和端口
server 10.8.0.13:19001 weight=5 max_fails=3 fail_timeout=30s;
}
# 提供转发的服务,即访问localhost:9001,会跳转至代理socket_proxy指定的转发地
址
server {
listen 19001;
proxy_connect_timeout 1s;
proxy_timeout 60s;
proxy_pass socket_proxy;
}