为什么这么麻烦?
自己也曾经被php调试配置搞晕,鼓捣过三次,有一次在咖啡店做了一个下午都没搞明白,今儿这是第三次研究,我感觉我终于明白了。这个东西的第一个疑惑就是,为啥还要这么麻烦的配置?其他的编程语言,比如c和python,也不用配置啥,在IDE里当时点个debug按钮就可以开始愉快的调试了。这是为什么呢?我很久都没搞懂,那就去查资料吧!
然而网上有太多关于phpstorm+xdebug怎么配置的文章,但是每篇都不太一样,测试一圈下来后真的好多文章的配置都是多余的,不得不说CSDN虽然在我不懂技术的时候给我了很大的帮助,但是有时候真的很误导人。吐槽归吐槽,那么为什么那么多人配置错误呢?我认为,一图胜千言,配置错误的人都不理解这张图:
参考:PhpStorm, XDebug, and DBGp Proxy
所以可以看到,在用xdebug+phpstorm调试php的过程中,是有三个角色的:
- 调试客户端:phpstorm
- 安装了xdebug需要被调试的php
- 触发调试的浏览器
所以三个角色放在一台电脑上,不晕才怪。这里我回答一下我之前的那个问题,为什么不能像其他语言一样,调试个php要这么麻烦的配置:根本原因是,看似是本地调试,实际和远程调试没有什么特别大的区别。因为即使是在本地,php解析器也是被apache/nginx等中间件调用。
其他的编程语言都是IDE负责去调用调试器,但是php是藏在中间件后面的,所以就需要phpstorm和真正需要被调试的php代码进行通信了,于是xdebug就是实现了这个通信机制的一个php插件。如果不明白为什么php是藏在中间后面的,那么就要了解一下php的运行模式了。
php的运行模式
总结下来就是:
- 可以通过php_sapi_name()获得当前php的运行模式的接口信息
- 如果中间件采用nginx,那么一般是fastcgi
- 如果是通过安装libapache2-mod-php结合apache和php的则是Module模式
- 如果是通过命令行参数
a\r\f
直接执行php则是cli模式,如下:
$ php –a # 交互式php shell
$ php –r "echo time();" # 直接执行php语句,不加<??>前后缀
$ php [–f] exp.php # 直接执行php文件
调试原理
搞明白了php的运行模式,我们也就能理解,为什么及时是在本地调试时也要进行一系列的配置了:就是让调试器(xdebug)和控制调试的客户端(phpstrom)可以通信。xdebug是藏在中间件后面的php的插件,而不是在phpstorm这侧。回到这张图:
理解原理后,我们其实只要完成以下三个步骤就可以愉快的调试了,三个步骤的顺序无所谓,都是配置:
- 配置phpstorm监听端口,打断点
- 浏览器安装xdebug helper插件,目的是触发调试(可选)
- 服务器的php安xdebug扩展,并配置php.ini
如果用过IDA的远程调试可以发现,IDA的远程调试是以调试的目标程序为server开放端口,等待调试器连接。而这里是目标程序接受到一个调试的信号,从而连接到IDE主机上所开的端口,进行通信以及调试,即:
client | server |
---|---|
IDA pro | idaserver |
php-xdebug | phpstorm |
最简调试配置
这里使用mac上的MAMP作为基础的web运行环境,在windows下一般使用phpstudy,方便进行版本切换。
配置网站根目录
这里我们假如调试的工程文件夹是debug,里面有一个index.php,那我们先正常配置MAMP,或者phpstudy的网站根路径为这个目录:
安装xdebug(MAMP)
在MAMP或者phpstudy中其实并不用安装xdebug,二者都自带了这个插件编译好的动态链接库,只需要点击按钮开启即可:
然后点击php版本右侧的箭头按钮即可配置php.ini,翻到最后即可找到关于xdebug的配置
一般默认配置就好,最重要的是如下三条:
xdebug.remote_enable=1
xdebug.remote_host=127.0.0.1
xdebug.remote_port=9000
这里的remote_host和remote_port就是要连接到的调试IDE的ip和port
安装浏览器xdebug helper插件
如果在php.ini里配置选项xdebug.remote_autostart=1,可以不装浏览器的插件了,怎么访问都进入调试。
phpstorm配置
这里网上有太多,关于phpstorm的配置了,其实只要配置完debug(应该是默认的),端口和之前的php.ini一致,就已经可以调试了。
配置完成!
不信?自己试一下!
此时可以看到已经成功的断下来了:
因为IDE只要开启监听就好,并不需要他来配置php的解析什么的。所以IDE在调试时要完成的功能是
- 监听端口
- 能打开站点源码
- 下断点
- 能修改源码
php运行配置详解
既然php调试这么简单就能配置完,也不用再phpstorm配置php解析器那网上的乱七八糟都在干什么?归根结底是不了解那张三角色的图,另外也不是了解jetbrains提供的run/debug configurations都是啥:
-
built-in web server 使用php内置的webserver启动服务,需要配置php解析器,之后就会使用
php -S localhost:8000
启动web服务,不需要中间件 -
http request使用这个配置,需要配置好服务器地址,这样点击run或debug时就phpstorm就会直接发送一个http请求
-
remote debug 这个是正儿八经的远程调试配置
-
php script 使用这个配置,需要配置php解析器,通过cli模式运行php代码
-
web page 一个正经的网站配置,具体和23的区别没研究
刚才只是随便open的一个文件夹,那正儿八经的php工程到底怎么建立,如下:
看到右侧的五种选项,应该是恍然大悟了吧!
xdebug安全问题
xdebug.remote_connect_back = 1
xdebug.remote_enable = 1
如果开启了xdebug.remote_connect_back选项,则不用配置remote_host,就是为了方便调试人员不必使用固定ip进行调试,会用$_SERVER[“HTTP_X_FORWARDED_FOR”]变量的值进行连接:
浏览器插件为:ModHeader
所以触发调试动作的主机,即可与服务器进行调试,这样就直接能获得调试信息,包括不被打印的变量等。