疑难杂症,可以通过服务器端的xdebug.remote_log进行诊断处理。
一、前言
初学PHP语言,一般会推荐notepad++等编辑器进行开发。但是入门之后,使用phpstrom等IDE好处多多,比如学习一些框架的时候,断点调试对于理解框架的整个运行机制和生命周期无可替代。在生产环境中,IDE的调试的变量监控对于提高开发效率也至关重要。当然了,每个行业都有前1%的人,程序员也不例外,使用VIM也未尝不可。
本篇的主要写作原因是,Xdebug配置对于新手来说问题多多,网上的教程多是一家之言,对于很多配置的官方文档来源语焉不详,缺乏对于可能存在的问题的调试办法,对于各种本地、远程等各种环境下的配置不做兼顾。本篇将就以上问题的每一个细节的来源、机理尽量加以说明,争取做到读者可以触类旁通,不必查找其他资料。
二、准备和系统说明
- 使用Vmware安装CentOS作为web开发机实践】
- 开发机配置的是Nginx + php7.0
- 所有步骤依赖Phpstorm的配置说明,即settings->Languages&Frameworks->PHP->Debug
特别注意,本文的全部内容都是按照下图的Pre-configuration里的4个步骤进行的。如果你遇到本文中没有涉及到的问题,可以点击第一步中的Validate debugger configuration on the Web Server进行调试,具体请参见本文四、4章节。
三、Xdebug的安装
1、点击上图中步骤一里install xdebug,进入phpstorm对xdebug的安装说明:
https://confluence.jetbrains.com/display/PhpStorm/Xdebug+Installation+Guide
phpstorm对xdebug的安装思路是,去xdebug官网下载编译好的二进制文件,拷贝到php的extention目录,然后在php.ini文件最后面加入如下配置(实际的例子见本文三、4):
[Xdebug] zend_extension=<full_path_to_xdebug_extension> xdebug.remote_enable=1 xdebug.remote_host=<the host where PhpStorm is running (e.g. localhost)> xdebug.remote_port=<the port to which Xdebug tries to connect on the host where PhpStorm is running (default 9000)>
2、 这里主要是针对windows服务器的php开发环境而言的,我们这里使用的是CentOS 7,因此,最便捷的安装办法是:
sudo yum search xdebug yum install xdebug.....
这时候,xdebug.so已经自动放入php的extention目录下了,比如zend_extension = /usr/local/php/lib/php/extensions/no-debug-non-zts-20151012/xdebug.so
3、 xdebug官网还可以编译安装xdebug,推荐这种安装方式。
- 首先打开xdebug wizard网址:
https://xdebug.org/wizard.php
php -i
命令输出的全部内容都放到里面去,解析后会给出详尽的安装步骤:
Tailored Installation Instructions Summary Xdebug installed: no Server API: Command Line Interface Windows: no Zend Server: no PHP Version: 7.0.15 Zend API nr: 320151012 PHP API nr: 20151012 Debug Build: no Thread Safe Build: no Configuration File Path: /usr/local/php/etc Configuration File: /usr/local/php/etc/php.ini Extensions directory: /usr/local/php/lib/php/extensions/no-debug-non-zts-20151012 Instructions Download xdebug-2.5.1.tgz Unpack the downloaded file with tar -xvzf xdebug-2.5.1.tgz Run: cd xdebug-2.5.1 Run: phpize (See the FAQ if you don't have phpize. As part of its output it should show: Configuring for: ... Zend Module Api No: 20151012 Zend Extension Api No: 320151012 If it does not, you are using the wrong phpize. Please follow this FAQ entry and skip the next step. Run: ./configure Run: make Run: cp modules/xdebug.so /usr/local/php/lib/php/extensions/no-debug-non-zts-20151012 Edit /usr/local/php/etc/php.ini and add the line zend_extension = /usr/local/php/lib/php/extensions/no-debug-non-zts-20151012/xdebug.so
上面1、2、3的思路都是得到一个xdebug.so的二进制扩展,然后将xdebug的相关配置放到php.ini文件里,下面对配置进行详细说明。
- 首先确定php.ini文件的位置,比如shell下
php -i | grep
,可以得到php.ini的路径 - 编辑php.ini文件,在最后面加入如下配置,官方说明见本文三、1,这里是一个实际配置的例子。
zend_extension=/usr/local/php/lib/php/extensions/no-debug-non-zts-20151012/xdebug.so xdebug.remote_enable =1 xdebug.remote_handler = "dbgp" xdebug.remote_host = "www.phpcms.com" xdebug.remote_mode = "req" xdebug.remote_port = 9001
对上述项逐项说明一下:
zend_extension
顾名思义是xdebug扩展的路径。xdebug.remote_enable
这里都要必须是1,如果不是1,无论phpstrom在虚拟机里还是在主机上,都不能进行调试。xdebug.remote_handler
这里的协议只能是dbgp,xdebug的官网文档是这样说的:Note: Xdebug 2.1 and later only support 'dbgp' as protocol.
xdebug.remote_host
是你要本地调试的域名,这里注意,不能填localhost或者127.0.0.1,除非你要调试的站点域名叫做localhost。也就是说,你要根据nginx或者apache里虚拟站点的配置确定这个叫什么。比如我这里的nginx站点配置文件是:
server { listen 80; server_name www.phpcms.com; …… }
注意,这里配置了www.phpcms.com为虚拟站点的域名,那么要在/etc/hosts里配置对应值,即 www.phpcms.com 127.0.0.1
xdebug.remote_host
的值就是www.phpcms.com。如果不是这样的话,本文二、3中的Validate xdebug configuration on the server
会报错remote host is configured as 'localhost' despite server host is probably not local
xdebug.remote_mode
req模式即脚本启动即连接,如果是jit模式,则是在脚本产生错误之后才连接。详情见xdebug关于远程调试的说明文档:https://xdebug.org/docs/remotexdebug.remote_port
这个是服务器开给远程ide的端口,默认是9000,注意,很多nginx的php-fpm监听端口也是9000,这时候改成非9000,或者将nginx站点配置文件和php-fpm监听改为unix sock,比如
server { listen 80; server_name www.phpcms.com; …… location ~ [^/]\.php(/|$) { #fastcgi_pass remote_php_ip:9000; fastcgi_pass unix:/dev/shm/php-cgi.sock; fastcgi_index index.php; include fastcgi.conf; } …… }
否则的话,会卡在`debug:waiting for incoming connection with ide key *
- 仅需要配置上述几项,其他的诸如下面的不需要配置,配上了也无影响:
;xdebug.idekey = ;xdebug.remote_log = "/tmp/xdebug_remote_log" ;xdebug.remote_connect_back =1
四、PHPSTORM的配置
特别注意,这里PHPSTORM是跑在虚拟机里的,CentOS 7 里,是Linux版。如果虚机是跑在主机上的,要把以下的127.0.0.1全部改成虚机的host only网卡的IP。然后在主机的hosts里配置对应的域名和ip。
3、PHPSTORM调试配置。Run->Edit Configuration,点击最左上角的绿色加号,这里我们调试的类型是PHP Web Application
,还有一种常用的调试是CLI脚本模式。然后Configuragion ->Server,点击…,弹出框里点击绿色加号,填写Host和Port,这两项要跟你的Nginx Server配置里的域名和端口相对应。返回之后,在Start URL里填写项目的起始地址。
特别注意,这个Start URL坑比较多。一个是建议写成如下图的绝对访问地址,带上入口文件index.php。为什么呢,因为Nginx的虚拟站点配置里,一般是首先识别index.html,而不是index.php。这样调试开始之后,打开了http://www.php.com,实际访问的是index.html而不是index.php,卡在
waiting for incoming connection with ide key
综上,强烈推荐按照下图的写法,绝对地址+入口文件:http://www.php.com/index.php
4、验证Server端和PHPSTORM端配置。settings->Langeuages & Frameworks->PHP->Debug,Pre-configuration里,第一步,点击Validate,弹出框里,Url填写http://www.php.com/
五、浏览器插件的配置
什么?还没配完,浏览器为什么还需要一个插件呢? 这里不得不说一下Xdebug调试的通信流程。下面直接粘一下Xdebug的官方说明,大概的流程是PHPSTORM向浏览器发起请求,浏览器通过DBGp协议返回给PHPSTORM,PHPSTORM同样通过DBGp协议把插入的信息返回给浏览器,最后浏览器将最终的返回结果给PHPSTORM用于调试和报错。具体可以参见https://xdebug.org/docs/remote的Communication Set-up With a static IP/single developer
官方说明:
With remote debugging, Xdebug embedded in PHP acts like the client, and the IDE as the server. The following animation shows how the communication channel is set-up: 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
具体安装插件,点击本文二、3中Pre-configuration图里的settings->Languages&Frameworks->PHP->Debug第二步,Install browser toolbar and bookmarklet。会跳转到这个网址:https://confluence.jetbrains.com/display/PhpStorm/Browser+Debugging+Extensions
具体网址:https://chrome.google.com/webstore/detail/xdebug-helper/eadndfjplgieldjbigjakmdgkmoaaaoc
六、调试
settings->Languages&Frameworks->PHP->Debug,Pre-configuration里,先validate一下设置。没有问题,第三步,Enable listening for PHP Debug Connection,这个在PHPSTORM界面的右上角也有。
在index.php的第一行打一个断点,就是再图中红点位置单击一下。然后点击右上角的小爬虫,或者菜单里Run-debug,PHPSTORM自动打开浏览器,如何判断已经成功了呢?这时候浏览器应该是空白并且是载入中的状态,而PHPSTORM的debugger窗口,则有一些全局变量已经被watch。恭喜,你可以像是用微软的开发环境一样调试PHP啦。
七、疑难说明
2、 ionCube加密组件则需要将其配置放前,否则会报错
PHP Fatal error: [ionCube Loader] The Loader must appear as the first entry in the php.ini file in Unknown on line 0
3、 php.ini文件中,xdebug.idekey应该如何配置?配置成’PHPSTORM’,或者留空,或者其他都没有影响,每次调试时会自动生成一个数字idekey,然后在打开浏览器时以参数的形式传过去。比如http://www.phpcms.com/index.php?XDEBUG_SESSION_START=11756
4. phpstorm卡在debug:waiting for incoming connection with ide key 。这里主要可能有两个可能的问题,一个是三、4服务器php.ini里的xdebug.remote_port
和四、2中PHPTSORT填写的端口不一致。另一个则可能是四、3中填写的URL没有实际访问到。还有一种可能是打的断点位置不对,不是每个地方的断点都可以执行到的,配置时建议打入口php文件的第一行。