使用XDebug加PHPStorm远程调试PHP

PHPStorm是一款非常强大的PHP IDE,一般来说,我们的PHP程序是运行在服务器端(服务器端一般是Linux),编辑在本地(一般是Windows),这样的开发模式,最麻烦的,就是写好代码,可能要编译,要上传,要重启,要调试。
好在,这些,PHPStorm都考虑到了。自动上传,建议使用PHPStorm的Deployment功能,只要映射好路径,一次配置,终身受益。
现在,我们单说说,如何远程调试。

安装xdebug

这是必要步骤,不安装xdebug也可以安装Zend的调试extention,之前我写过一篇使用zend studio的介绍,参考 http://mnstory.net/2013/10/zendserver-zendstudio-install-usage/ 。xdebug的安装比较麻烦,如果发行版不自带,就要从源码安装,源码安装,又依赖于php的devel包,我们的php是自己编译的,编译php前,又要使用到apache的apxs,所以还得编译apache。
假设 所有的编译,都在$build目录进行。

  1. 编译apache
    进入Apache源码目录:

    1
    cd $build/httpd-2.2.31

    执行configure,编译后输出到哪个目录,可以指定一下,我统一到$inst:

    1
    ./configure --prefix=$inst/apache --enable-so --enable-module=shared --enable-mods-shared='rewrite headers expires ssl'

    执行编译:

    1
    make -j8 && make install
  2. 编译php
    进入 php源码目录:

    1
    cd $build/php5

    执行configure,同样指定输出目录,with apxs2是用来支持apache的,有这个会生成libphp5.so。

    1
    ./configure --prefix=$inst/php5 --with-apxs2=$inst/apache/bin/apxs

    执行编译:

    1
    make -j8 && make install

    有的人,将 && 写成 &,这是不正确的。

  3. 编译xdebug

    • 下载
      编译xdebug前,要先下载xdebug源码,一般的方法是,将phpinfo()输出的网页,copy到 https://xdebug.org/wizard.php,其会给出对应版本的xdebug下载链接。
    • 编译
      进入xdebug源码目录执行:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      [compiler xdebug]# $inst/php5/bin/phpize
      Configuring for:
      PHP Api Version: 20131106
      Zend Module Api No: 20131226
      Zend Extension Api No: 220131226
      [compiler xdebug]# ./configure --with-php-config=$inst/php5/bin/php-config
      [compiler xdebug]# make && make install
      [compiler xdebug]# ls
      $inst/php5/lib/php/extensions/no-debug-non-zts-20131226/xdebug.so
    • 安装

      找到运行环境的php安装根目录,假设为$phproot,将xdebug.so放到目标机的 $phproot/lib/php/extensions 目录。把下面的信息添加到 $phproot/lib/php.ini

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      zend_extension = $phproot/lib/php/extensions/xdebug.so # 这个$phproot记得替换成你的路径
      [xdebug]
      xdebug.idekey = "PHPSTORM" #因为DBGp调试代理是可以做调试分发的,所以,定义一个IDEKEY,目的是让调试器知道,是不是发给自己的请求
      xdebug.remote_enable = 1 # 设置为1的时候,会先参数链接到remote_host和remote_port指定的调试器端口,如果连接不上,就继续执行,类似设置了0
      #xdebug.remote_mode = "req" # 有两个值,"req"(默认)表示一旦脚本开始执行,Xdebug就将尝试连接到调试客户端;"jit"当错误发生时,才尝试连接到调试客户端
      #xdebug.remote_handler = "dbgp" # 也就是调试走哪种协议,有老的PHP3协议,也有GDB协议,DBGP是当前的默认协议,也是当前主流支持的协议
      xdebug.remote_connect_back = 0 # 如果为1,xdebug会通过$_SERVER[‘REMOTE_ADDR’]变量,向发起HTTP请求的客户端发起链接,和remote_host功能类似,但是优先级比remote_host高,所以,设置了这个选项就会忽略remote_host,由于我的运行时服务器不能主动链接IDE所在PC,所以不能开启自动回连模式(内网访问外网的网页,也不能开启)
      #xdebug.remote_host = "localhost" #默认当然是本机了
      xdebug.remote_port = 9909 # 默认端口是9000,由于担心服务器端口冲突,我修改为9909,建议你没有端口冲突时不修改
      #xdebug.remote_autostart = 0 # 这个为1,会忽略COOKIE或者POST/GET中带的XDEBUG_SESSION参数,不管有没有,都会启动调试,所以,还是设置为0比较好,默认0

      上面的配置是什么意思,请参考这个地方:http://www.xingfeilong.cn/article/2013-08-28/86.shtml

      如果

      1
      zend_extension=xdebug.so

      写成了

      1
      extension=xdebug.so

      会报错:

      1
      16:18 Cannot accept external Xdebug connection: Cannot evaluate expression 'isset($_SERVER['PHP_IDE_CONFIG'])'

      重启Apache,再用phpinfo()查看,就能搜索到xdebug模块相关的信息了。

配置代理

一般用户不需要这一步,我是由于内网远程调试外网服务器代码,所以需要反向代理。上面说了,我的运行时服务器不能主动链接IDE所在PC(类似于本地调试公网服务器上的代码),所以,需要做反向代理,因为是的windows上连接服务器使用的是xshell,于是直接利用xshell配置隧道:
reverse proxy

上图的配置代表,运行时服务器连接本机的9909,会转到IDE所在的PC 9000端口(当然,你的XSHELL得先从PC上连接到运行时服务器)。

1
2
3
4
[server ~]# netstat -nap | grep 9909
tcp 0 0 127.0.0.1:9909 0.0.0.0:* LISTEN 18152/sshd: root@pt
tcp 0 0 127.0.0.1:9909 127.0.0.1:50152 ESTABLISHED 18152/sshd: root@pt
tcp 0 0 127.0.0.1:52150 127.0.0.1:9909 ESTABLISHED 17029/httpd

IDE配置

  1. 先从服务器上获取源码
    虽然我们可能只修改一小部分源码,但是为了调试清晰,可以把相关源码全部下载下来,但是,往往相关源码不在同一个目录,下载下来后,可以在外层创建一个目录,让所有源码包含在工程内,方便对工程内不同路径做映射。

    解压到PC上的任意目录,再用PHPStrom从这个目录创建一个工程。

  2. 配置调试服务器和映射关系
    打开File菜单 -> Settings -> 左树 Languages & Frameworks / PHP / Servers -> 新建一个Server,输入服务器的IP和端口,最关键的是,将本地工程文件夹和服务器上的文件夹对应起来,方便调试的时候找到源码:
    server-config

  3. 配置DEBUG
    打开Run菜单 -> Edit Configurations -> 选择模板PHP Remote Debug,创建一个新的配置,Servers就选择刚才配置的,Ide Key设置为php.ini里面xdebug.idekey设置的。
    debug-configure

  4. 安装浏览器插件xdebug helper
    在浏览器端,安装xdebug helper插件,由于chrome应用商店被墙,此插件可以自行搜索,安装好后,再插件的选项配置中,IDE key配置为PhpStorm,然后选择Debug模式,再打开PHP页面时,通过chrome F12可以看到,cookie里面会带有:

    1
    Cookie:XDEBUG_SESSION=PHPSTORM

    此插件的唯一目的就是在请求里加入 XDEBUG_SESSION=PHPSTORM,若你没有安装,可以试试手动在URL参数里加入,当然,也可以在之前配置php.ini的时候,设置 xdebug.remote_autostart = 1

  5. 调试
    打开监听,下断点,这个时候,再次访问浏览器,如果所有配置都正确,PHPStorm会在你的断点处暂停下来。
    debuging