> 工欲善其事必先利其器,学习一门新语言,调试器的使用必不可少,本文分享一下PHP调试器的使用。
PHP目前有两种流行的调试器,
我在学习和研究过程中,发现网上的各种信息过于凌乱,感到痛苦,影响理解和使用。今天我以Xdebug为例,先解释其基本的工作原理,再说明生产过程中如何使用,希望能带给大家清晰易懂的知识。
Xdebug
Xdebug是一个PHP扩展,它采用DBGp协议,提供了对PHP进行Debugging和Profiling的能力。
Debug信息包含:
-
stack and function traces in error messages with:
- full parameter display for user defined functions
- function name, file name and line indications
- support for member functions
- memory allocation
- protection for infinite recursions
此外,Xdebug还提供以下功能:
- profiling information for PHP scripts
- code coverage analysis
- capabilities to debug your scripts interactively with a debugger front-end
今天只讨论Debug,其它功能以后有机会再分享。
Debug原理
原文参考:https://xdebug.org/docs/remote
简单来说,XDebug调试是一种C/S结构,Client是PHP-Xdebug插件,Server是我们的IDE(或者各种Editor插件),中间通过DBGp协议通信。PHP脚本在运行时,由Xdebug插件向IDE发起连接,将调试信息发送给IDE,并通过DBGp协议进行互动。
看下图,就明白了:
- The IP of the server is 10.0.1.2 with HTTP on port 80
- The IDE is on IP 10.0.1.42, so xdebug.remote_host is set to 10.0.1.42
- The IDE listens on port 9000, so xdebug.remote_port is set to 9000
- The HTTP request is started on the machine running the IDE
- Xdebug connects to 10.0.1.42:9000
- Debugging runs, HTTP Response provided
以上是单人模式,在php.ini中配置了IDE的IP地址以及监听的端口。这种模式的缺陷是配死了IDE目标,不能支持多用户调试。所以Xdebug还提供了一种多用户的调试模式,这种模式无需配置remote_host,而是配置xdebug.remote_connect_back=On,Xdebug会记下来访地址,作为调试时的连接目标。调试过程如下:
- The IP of the server is 10.0.1.2 with HTTP on port 80
- The IDE is on an unknown IP, so xdebug.remote_connect_back is set to 1
- The IDE listens on port 9000, so xdebug.remote_port is set to 9000
- The HTTP request is made, Xdebug detects the IP addres from the HTTP headers
- Xdebug connects to the detected IP (10.0.1.42) on port 9000
- Debugging runs, HTTP Response provided
搞明白了原理,那我们就开始实践吧。
安装Xdebug
根据各自不同的工作站平台,参考官方安装指导.
安装的时候注意一下输出信息,记下安装好的扩展包位置,下一步配置PHP时会用到。
配置PHP-Xdebug
打开php.ini(不知道php.ini在哪里的,可以输出phpinfo()看看),然后加上对Xdebug扩展的配置:
[Xdebug]
zend_extension="/usr/lib/php/extensions/no-debug-non-zts-20131226/xdebug.so"
xdebug.remote_enable=On
xdebug.remote_enable=On,表示打开远程调试开关,这是必须的。
然后,有两种方法可以验证一下插件是否加载成功:
-
命令行执行php -v,看看
![pic](http://imgur.com/3UbEnNo.png)
-
网页输出phpinfo()
![pic](http://imgur.com/r3I8FZF.png)
以上输出若能看到Xdebug版本信息,就ok了。另外,在phpinfo中,可以看到xdebug的配置信息,搜搜看,这些配置都是可以在php.ini中进行修改的,各自代表的意思大家可以查官网,这里就不详述了。
配置IDE
以PHPStorm为例,PHPStorm实现了DBGp协议,我们需要配置它监听的端口,这个端口号需要与xdebug.remote_port一致,才能确保调试时PHP-Xdebug能连上IDE。
以下是默认配置,如果没有冲突可以不用改。在帮其他同学trouble shooting时,发现php-fpm和xdebug默认都使用9000号端口,真是一个奇怪的配置啊,难道他们俩不应该经常被同时使用吗?如果你发现自己的debug不能正常工作,不妨检查一下这一点,将他们调整为不同的端口。
开始Debug
之前说过,IDE是作为一个Server的角色监听特定端口,等待Xdebug来连接,对于PHPStorm开启监听非常简单,直接点击右上角的“小电话”按钮:
变成
然后在代码里面打下断点。
接下来,开始运行并调试代码。针对不同类型的应用,方法也不一样。但目的都是相同的,就是要告诉PHP-Xdebug,我要开始调试了,给我把调试信息发过来!
Web App
两种方法:
- 在请求的URL地址后面加一个QueryString:XDEBUG_SESSION_START=session_name(当然用POST参数也可以),这样PHP-Xdebug就会知道该连接IDE调试了。
其实IDE提供了快捷的操作方式,不用你手动写URL参数。见Debugging PHP Web Applications with Run Debug Configurations,简单来说,就是你需要配置好Web Server,PHP Web Application,再点击后上角的“小瓢虫”按钮,IDE就会自动打开浏览器,帮你输好网址,并添加QueryString:XDEBUG_SESSION_START=session_name。
-
安装浏览器插件,插件会在你请求一个PHP页面时,带上一个XDEBUG_SESSION Cookie,这样就不用在URL上带参数了。
支持的插件:
- Firefox: the-easiest-xdebug
- Chrome: Xdebug helper
- Safari: xdebug-toggler-for-safari
- Opera: xdebug-launcher
试试以上两种方法,断点命中!开始享受调试。
Console
一般用在命令行程序或者单元测试的调试中。
我们需要通过设置环境变量XDEBUG_CONFIG来通知Xdebug进行调试。当然,我们可以向这个环境变量中添加更多的设置来配置Xdebug(这些配置都可以在php.ini中进行设置)。
export XDEBUG_CONFIG="idekey=session_name"
php myscript.php
断点命中!
不想调试了,释放掉这个环境变量。
unset XDEBUG_CONFIG
小技巧,如果你用Zsh,可以为上述两段小代码设置别名。
alias xdebug-on="export XDEBUG_CONFIG=\"idekey=PHPSTORM\""
alias xdebug-off="unset XDEBUG_CONFIG"
PHPStorm也提供了快捷的操作,见Debugging PHP CLI scripts with PhpStorm
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。