可能是全网最详细的PhpStorm+xdebug远程调试php代码的教程

可能是全网最详细的PhpStorm+xdebug远程调试php代码的教程

名词解释:IDE,是“Integrated Development Environment”的缩写,中文翻译成“集成开发环境”,phpstorm就是一个集成开发环境(因为它不是简单的一个编辑器,它具有各种追踪调试功能),此外像ZendStudio也是集成开发环境,而像sublime、vscode、Notepad++等就只是一个编辑器而不是集成开发环境(即不是IDE)。

本文是配置phpstorm+xdebug(远程)调试的教程,所以默认你已经安装好了xdebug,如果没有安装,这是xdebug官网,你可以看看。

xdebug调试原理

  • 1、IDE(比如phpstorm)中已经集成了一个遵循DBGp协议的Xdebug插件,当点击IDE上的监听按钮(像电话形状的按钮)时,IDE就会在本地监听指定的端口(端口号可配置);
  • 2、点击IDE上的debug按钮(即小虫子按钮),则会自动在浏览器打开配置好的链接,并在链接后自动添加?XDEBUG_SESSION_START=19435这样的一个参数;
  • 3、由于有XDEBUG_SESSION_START参数,而xdebug是php的扩展,所以xdebug会接收到这个参数并开启debug功能,然后xdebug会通过DBGp协议向xdebug配置中指定的ip和端口(在php.ini中指定该ip该端口)发送一个请求,而IDE刚好在监听该端口,所以IDE能接收到xdebug的请求,此时xdebug与IDE之间会建立连接(使用DBGp协议通讯),并且IDE会把断点信息发送给xdebug;
  • 4、xdebug收到了断点信息后,就知道运行到哪一行时需要停止并把debug数据返回给IDE,IDE接收到debug数据就会在IDE中显示出来,于是我们就能看到debug数据;
  • 5、当我们点击IDE上的debug按钮(例如step over, step into, step out)时,IDE又会把这个指令发送给xdebug(通过DBGp协议),xdebug接收到后,就知道应该要step over、step into还是step out等等,并且把执行结果返回给IDE,如此往复。

该步骤可参考xdebug官方文档,在Step Debugging中页内查找“Communication Set-up”往下移动一下即可看到。

详细的步骤,打开6.3 IDE to debugger engine communications,往上滚动即可看到IDE与DBG对话过程。

配置xdebug参数

由前面的原理我们知道,我们需要给xdebug配置一个ip和端口,给phpstorm配置一个监听端口。

由于xdebug是php的扩展,所以xdebug的参数我们是在php.ini中配置的,把以下的参数加入到php.ini文件中并重启php-fpm

[xdebug]
zend_extension="/path/to/xdebug.so"
;开启xdebug远程调试功能,On或1都表示开启
xdebug.remote_enable=On
;是否自动开启调试,Off/0都表示不开启
xdebug.remote_autostart=Off
;指定IDE所在电脑的ip或域名(暂时指定本机,即127.0.0.1)
xdebug.remote_host="127.0.0.1"
;打开后,xdebug会忽略remote_host值并自动从$_SERVER中获取来源ip
xdebug.remote_connect_back=On
;指定IDE debug端口(xdebug需要通过该端口与IDE通讯)
xdebug.remote_port=9002
;固定填dbgp(因为目前只支持这个协议,也只有这个协议)
xdebug.remote_handler="dbgp"
;这是一个所有网上的文章都提到要设置但实际上却没啥用的参数(不信你可以注释掉试试,一切都正常)
xdebug.idekey="PHPSTORM"

在xdebug3.0以后,很多参数都改名了,如下所示(添加于2022.07.28),文章中其它部分还有很多地方是用3.0以前的参数的,大家自行对应一下,把它们对应到3.0以后的新参数就行,3.0修改的参数文档在:这里

[xdebug]
zend_extension="/path/to/xdebug.so"

;xdebug3.0中用于代替之前的xdebug.remote_enable=On
xdebug.mode=debug

;xdebug3.0中用于代替之前的xdebug.remote_autostart,trigger对应之前的off,yes对应之前的on
xdebug.start_with_request=trigger

;xdebug3.0中用于代替之前的xdebug.remote_host
xdebug.client_host="127.0.0.1"

;xdebug3.0中用于代替之前的xdebug.remote_connect_back=On,它会自动从$_SERVER['HTTP_X_FORWARDED_FOR']
;或$_SERVER['REMOTE_ADDR']变量中获取ip,当然因为$_SERVER只有服务器模式有所以客户端模式是用不了的(可配置其它变量)
;如果找不到ip它会回退(fallback)到xdebug.client_host指定的ip
xdebug.discover_client_host=true

;xdebug3.0中用于代替之前的xdebug.remote_port
xdebug.client_port=9003

;固定填dbgp(因为目前只支持这个协议,也只有这个协议)
xdebug.remote_handler="dbgp"

;这是一个所有网上的文章都提到要设置但实际上却没啥用的参数(不信你可以注释掉试试,一切都正常)
xdebug.idekey="PHPSTORM"

其中zend_extension中的路径要修改成你的路径,如果在编译php时指定了extension_dir,那么直接用zend_extension="xdebug.so"即可,不需要写路径。

怎样确定你有没有配置extension_dir呢?可以在phpinfo()中查找,比如我的就有:
-w936

xdebug调试代码的相关参数,在Step Debugging中搜索“Related Settings”即可找到,所有可配置选项可查看Documentation – all settings

配置phpstorm debug端口

在phpstorm设置界面,找到下图所示位置并修改成你想要的端口
-w980

点击电话图标开启监听端口(我这里的电话图标已经是监听状态,非监听状态电话图标的左上角是红色的🚫符号)
-w365

Mac可用lsof命令查看端口是否已正常监听:

lsof -i:9002
 bruce@Bruce's MBP > lsof -i:9002
COMMAND   PID  USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
phpstorm 1619 bruce   18u  IPv4 0xb8ebdbf76bb13721      0t0  TCP *:dynamid (LISTEN)

Windows使用netstat命令查看端口是否已正常监听:

netstat -ano | findstr "9002"
PS C:\Users\bruce> netstat -ano | findstr "9002"
  TCP    0.0.0.0:9002           0.0.0.0:0              LISTENING       6788
  TCP    [::]:9002              [::]:0                 LISTENING       6788

Linux可用netstat命令查看端口是否已正常监听:

netstat -tulnp | grep -v "grep" |  grep 9002
xiebruce@centos-linux1 > netstat -tulnp | grep -v "grep" |  grep 9002
tcp        0      0 127.0.0.1:9002          0.0.0.0:*               LISTEN      16568/sshd: xiebruc
tcp6       0      0 ::1:9002                :::*                    LISTEN      16568/sshd: xiebruc

添加要debug的网站

你要debug哪个网站,需要添加它的信息,比如域名,端口,使用xdebug还是使用Zend debugger调试器以及路径映射等等信息。


添加非远程调试服务器
-w979

添加远程调试服务器
-w1172
远程调试基本上跟添加非远程服务器一样,只不过多一个步骤,就是勾选Use path mappings(使用路径映射功能),映射的原因,是假如你要debug的那个php文件在远程服务器中的绝对路径跟你本地的不同时,如果没有这个路径映射,则phpstorm将无法debug这个文件(因为根据远程服务器上的文件路径在本地找可能找不到),而设置了映射,它就会在映射目录下找,那肯定就找的到。

添加debug配置

RunEdit Configurations或右上角下图所示位置点击Edit Configurations
-w556

点击+号,如下图所示,目前我试过的就是“PHP Remote Debug”、“PHP Script”、“PHP Web Page”这三个,其中“PHP Script”用于命令行方式的debug,而“PHP Remote Debug”和“PHP Web Page”都是网站方式(走php-fpm)的debug
-w761
上图中的“PHP Remote Debug”和“PHP Web Page”,从名字上看,一个是远程,一个是网页,但实际上这两个可以相互替换,比如就算我是本地调试(php代码与phpstorm在同一台电脑上)也可以用“PHP Remote Debug”,就算我调试远程代码(被调试的php代码在远程服务器上)也可以用“PHP Web Page”。

据我测试,“PHP Remote Debug”和“PHP Web Page”的区别,就是“PHP Remote Debug”点击下图的小虫子后,不会自动跳转到浏览器打开配置里的域名,而是直接在phpstorm底部弹出debug窗口。而对于“PHP Web Page”,点小虫子后会自动在浏览器打开配置里的域名并在域名后添加XDEBUG_SESSION_START=xxxx开启debug
-w370

既然“PHP Remote Debug”点击虫子后不会自动跳转到浏览器访问配置里指定的域名并在域名后添加XDEBUG_SESSION_START=xxxx开启debug,那要怎么开启debug呢?答案是自己在浏览器里用Xdebug helper浏览器扩展来开启(实际上就是发送一个名为“XDEBUG_SESSION”的cookie而已)
-w133
当然,你手动在浏览器添加XDEBUG_SESSION_START=xxxx一样可以开启。

添加PHP Web Page

接着上边的内容,如果你要网页调试(不管是远程还是本地)都可以添加PHP Web Page(当然也可添加PHP Remote Debug)。

点击+PHP Web Page后页面如下
-w805

Name是自定义的名称,它最终会出现在下图所示的位置,可以添加多个PHP Web Page,每次debug的时候,选择要按哪个配置来debug
-w532

Allow parallel run表示可以运行多个实例互不影响(不勾选的话,如果你要调试同一个配置,它会替换原来正在运行的,相当于重启调试,而勾选了Allow parallel run就相当于新建一个调试,感觉这个一般不需要,如果你需要就勾选一下)

Server就是选择一下前面新建的Server(即选择要调试哪个网站)。

Start URL表示当你点击小虫子开启debug的时候,自动在浏览器打开哪个路径,比如我填的是/,它就会拼到我的域名test.xiebruce.top后面,假如我填的是/test.php,那么它就会在浏览器自动打开test.xiebruce.top/test.php,当然这个并不是很重要,因为点击小虫子的唯一作用,只是自动在浏览器打开你配置的网站路径并在URL后面添加XDEBUG_SESSION_START=xxxx而已,你自己在浏览器URL上添加也是一样可以的,但更多的是用Xdebug helper

添加PHP Remote Debug

根据前面所说,如果你要网页调试(不管是远程还是本地)都可以添加PHP Remote Debug(当然也可添加PHP Web Page)。

点击+PHP Remote Debug后页面如下
-w804
可以看到,这里就跟“添加PHP Web Page”有一点不同,就是这里不用填Start URL,但是有一个IDE key(session id)

没有Start URL很正常,前面已经说过,如果选择的是PHP Remote Debug,则点击小虫子后是不会自动在浏览器打开所配置的域名的,而是直接在phpstorm底部打开debug窗口,不会在浏览器打开,Start URL就没有意义了,所以不需要填Start URL

至于IDE key(session id),说实话我有点不太明白为什么要填,实测局域网远程测试,两台电脑上的phpstorm用同一个IDE key(session id)都能正常debug,也许是用来区分同一台电脑上开两个phpstorm分别打开不同项目时用的吧。

开启debug的方法

xdebug调试原理第2点我有提到,点击IDE上的debug按钮(即小虫子按钮),则会自动在浏览器打开配置好的链接,并在链接后自动添加?XDEBUG_SESSION_START=xxxx这样的一个参数(xxxx是任意字符串),php那边会接收到这个参数进而xdebug会开启debug,但其实这只是其中一种方法。

事实上XDEBUG_SESSION_START除了可以通过GET传参,还可以通过POST传,此外还可通过在cookie里传,只不过在COOKIE里传,COOKIE名是XDEBUG_SESSION而不是XDEBUG_SESSION_START,但值还是一个随机字符串。你可以在Step Debugging中页内搜索“HTTP Debug Sessions”可以找到开启debug的方式。

既然GET、POST、COOKIE传参都可以开启debug,那哪种方式最方便呢?

GET参数方式

首先看URL添加GET参数方式,你可以手动在URL后添加?XDEBUG_SESSION_START=xxxx或者点击小虫子会自动跳转添加,但无论哪种方式都不方便,手动添加肯定不方便,而点击小虫子每次都是跳转到Start URL指定的路径,但我要调试的路径可能并不是Start URL指定的路径,虽然你可以修改Start URL,但如果经常调试,路径经常变,每次都修改Start URL也很麻烦。

事实上使用GET参数方式,最终也会自动添加一个COOKIE,这就是为什么你使用GET参数方式开启debug后,即使把GET参数去掉,再刷新页面还是会开启debug的原因,删掉这个COOKIE就不会开启了
-w906

POST参数方式

而POST方式,是当你php里有post请求的时候,顺便带上这个参数来开启debug,但如果页面没有post请求,就不方便了。

COOKIE

既然前面两种都不方便,现在只剩COOKIE方式,看来COOKIE应该是最方便的了?事实上也是如此。但是我们怎么添加XDEBUG_SESSION这个COOKIE呢?因为如果手动添加COOKIE肯定也是麻烦。

其实实际上并没有那么麻烦,因为有一个插件可以使用,这个插件在Chrome浏览器上叫Xdebug helper(需要扶墙安装)。其它浏览器如果是chrome内核也可以安装这个,如果不是chrome内核,基本上只有Safari和firefox不是chrome内核了吧?

firefox扩展搜索xdebug会有很多,不过我可能会用这个Xdebug-ext,虽然Xdebug Helper for Firefox在Firefox上也有,但是它的位置是在这里(如下图,要开启或关闭调试至少要点击3次,太麻烦)
-w428

Chrome内核浏览器安装好Xdebug helper插件后,右击→Options可以对它进行设置
-w526

其实就是设置IDE key,它这里直接让你选择,如果是PhpStorm,IDE key就是PhpStorm,并且不能修改,如果要修改IDE key的值可以选择Other,其实IDE key是什么并不重要,它就是一个任意字符串(你写aaaa,bbbb也行)
-w1436

而firefox也差不多,右击有个选项,里面可以填IDE key,但其实也没必要配置,因为IDE key是什么并不重要,只要非空字符串并且不跟其它人(多人调试时)相同即可
-w341

命令行开启debug方式

前面说的GET、POST、COOKIE都是开启调试网页的方式,但是,即使是网站的php代码,也未必不能手动用命令行方式执行,举个最简单的例子,在网页中执行:http://localhost/test.php跟我直接用命令行php /path/to/test.php执行的结果并没有什么不同,只不过一个是在网页上输出,一个是在终端工具中输出而已(如果有输出的话)。

命令行开启的方式,是在终端中设置一个变量XDEBUG_CONFIG="idekey=xxxx",怎么设置呢?

Mac/Linux可用export设置

export XDEBUG_CONFIG="idekey=xxxxx"

Windows可用set命令设置

set XDEBUG_CONFIG="idekey=xxxxx"

而且Mac/Linux是可以把设置命令放到~/.bashrc~/.zshrc里,而Windows就不能,不过Windows也有方法实现(修改注册表),需要的请网上查资料,因为一般情况下,在需要调试时直接执行一下命令就好了,不需要它一直起作用。

如果是远程,除了要添加上边的XDEBUG_CONFIG,还需要添加这个

PHP_IDE_CONFIG="serverName=www.example.com"

其中www.example.com是你要调试的网站域名(即你在添加要debug的网站中添加的域名),因为只要涉及到远程,就需要代码路径映射,否则就会由于远程路径与本地路径对不上而无法调试。

在Linux/Mac上export就行,在Windows上就把export换成set
-w616
如上图,设置后,可用echo来查看是否设置成功(注意设置的时候不用$,但echo的时候,即使用的时候,就要$)。

远程debug的原理

其实根据前面的原理可知,想要使用phpstorm+xdebug来调试php代码,就必须保证phpstorm与xdebug能“相互通讯”,所以,所谓的远程debug,只要找到一种方法,让你的phpstorm能与xdebug“相互通讯”即可,只要明白了这个,你就能寻找解决方法。

注意:在以下所有类型的远程debug里,都需要保证远程的代码跟本地的代码完全一致,否则调试肯定会出问题。

局域网远程debug

局域网远程debug,是指php代码所在的服务器在内部局域网,你电脑的ip跟服务器的ip同网段,可通相互ping通。例如公司内部有开发服务器,每个人在服务器都建有一个账号,每个人都把代码部署在自己的账号下,phpstorm通过sftp上传,这样几乎相当于本地开发。

假设局域网远程主机只有你一个人用,那么你可以在php.ini里指定xdebug.remote_host的值为你本地电脑的ip(即phpstorm所在的那台电脑的ip),这样当xdebug开始debug后,就会与xdebug.remote_host所指定的ip及xdebug.remote_port指定的端口连接,这样phpstorm就能与xdebug通讯,只要它们能正常通讯,那么debug就不会有问题。

但如果是像前面说的,是多人开发,你就不能把xdebug.remote_host的值指定为你电脑的ip,如果指定了,那别人就无法debug了,因为xdebug只会与xdebug.remote_host指定的ip或域名通讯。

多用户debug需要添加以下配置(在配置xdebug参数的基础上添加以下配置)

xdebug.remote_connect_back=On

使用这个配置后,xdebug.remote_host设不设置都可以,你不设置(把它注释掉)它也会默认为localhost,但是只要xdebug.remote_connect_back=On启用,xdebug就不会使用xdebug.remote_host指定的ip或域名去连接phpstorm,而是会自动从php的$_SERVER['HTTP_X_FORWARDED_FOR'](使用了反代)和$_SERVER['REMOTE_ADDR'](未使用反代)这两个变量中获取来源ip地址(因为这个地址就是phpstorm所在机器的地址),这样自然就能获取到每个人的地址,当然,就算只有你一个人用,你也可以用xdebug.remote_connect_back=On而不用指定xdebug.remote_host的方式,这样就不用管是一个人还是多个人了。

另外需要注意,多人开发debug,最好保证相互之间URL中的XDEBUG_SESSION_START值或COOKIE中的XDEBUG_SESSION值不同,比如用各自姓名拼音(但实际上测试,就算相同也没问题)。

外网远程debug(单用户)

外网远程调试,主要是要使用ssh远程端口转发(ssh反向隧道)来让外网远程主机能“访问”位于内网的电脑里(phpstorm所在电脑)。

由于使用了ssh端口转发,所以xdebug配置必须保证remote_host的值为127.0.0.1localhost,因为xdebug的数据传输请求会被ssh隧道传输到你的电脑上,在你的电脑上用127.0.0.1localhost肯定能连上phpstorm

xdebug.remote_host="127.0.0.1"

并且要保证remote_connect_back值为Off(不写这行或注释掉默认为Off),因为一旦开启这个,remote_host就会被忽略,根据前面知识可知,remote_connect_back是自动识别来源ip用的,然而由于phpstorm所在机器的ip并非公网ip,所以识别到的ip肯定连不上(因为识别到的ip是你所在的网络环境的公网ip,即百度搜索“ip”出来的那个ip,这个ip并非你自己电脑的ip)

xdebug.remote_connect_back=Off

在phpstorm所在的电脑上运行以下命令,会在[email protected]服务器上监听9003端口(你没看错,虽然命令是在你电脑上执行,但却会在远程服务器上开启一个端口监听)

ssh -f -N -R 9003:localhost:9002 [email protected]

当使用网页请求并在URL中带上XDEBUG_SESSION_START=xxx参数或在COOKIE中带上XDEBUG_SESSION=xxx参数,xdebug即会开启debug,并向xdebug.remote_host指定的ip(即127.0.0.1)及xdebug.remote_host指定的端口发送请求,而这个端口刚好是ssh隧道在服务器端的端口,于是请求会从服务器经过ssh隧道传回本地,并在本地请求localhost:9002(而这刚好是本地phpstorm监听的端口),这样phpstorm就能跟xdebug通讯,从而完成远程debug。注意,以上的9003你写9002也可以,我故意写成9003方便区分命令中的哪个端口是表示在服务器上监听的端口。

关于ssh端口转发相关知识,如果想详细了解,可查看:SSH端口转发(SSH隧道)


以上方式只适合单人调试,无法多人调试,如果完整的把前面内容看完的童鞋,应该知道为什么。前面的局域网多人调试,是开启了remote_connect_back选项,采用自动识别来源ip的方式来完成的,但这仅限局域网,外网就不行了(除非你电脑有公网ip就可以)。

既然是使用ssh端口转发,理论上可以使用不同的端口来区分不同用户,比如

# 张三电脑运行
ssh -f -N -R 9003:localhost:9002 [email protected]
# 李四电脑运行
ssh -f -N -R 9004:localhost:9002 [email protected]

这样,服务器上就会监听9003和9004端口,这样不就能区分了吗?理论上这样确实能区分,但是xdebug是怎么知道要把请求发往哪个端口的?熟悉前面内容的童鞋应该知道,xdebug是通过xdebug.remote_port参数知道端口的,然而问题来了,这个参数只能设置一个端口,你前面设置的两个端口对它来说,只能用一个,所以ssh隧道无法解决多用户问题。

外网远程debug(多用户)

从外网远程debug(单用户)中可知,按目前的方式是无法实现外网多用户远程debug的,那怎么办?

据我目前所知这个问题基本上可以说是无解,即使用xdebug官网的DBGp Proxy Tool或PhpStorm推荐的KOMODO REMOTE DEBUGGING PACKAGE DOWNLOADS也无法解决该问题。

DBGp Proxy Tool,它名字都有个Proxy了,那就是个代理呗,其实就是个数据转发器,很容易想到,xdebug直接跟phpstorm无法解决多用户问题,那就把xdebug连接DBGp Proxy,然后让DBGp Proxy把数据转发给phpstorm,如下图:

                                 |-->phpstorm
php-fpm(xdebug)<-->DBGp Proxy<-->|
                                 |-->phpstorm

由上图可知,phpstorm跟DBGp Proxy之间还是要通讯的,而要通讯就涉及到远程和本地,如果把DBGp Proxy放在php-fpm所在服务器,那毫无疑问phpstorm还是无法直接跟它连接,还是得通过ssh隧道,而如果每个开发者一个隧道的话,那隧道端口就必须不同,而DBGp Proxy也只能监听一个端口,所以还是无法解决。

唯一可能的解决方法是,公司内部有一个有公网ip的网关(用人话说就是路由器),把DBGp Proxy运行在这路由器上,又或者公司内部有一台有公网ip的服务器,把DBGp Proxy运行在这台服务器上也行,因为有公网ip,所以DBGp Proxy跟外网服务器上的xdebug就能直接连接(直接把xdebug.remote_host设置为你公司那台外网服务器的ip即可),而你公司服务器上的DBGp Proxy肯定也能跟内网中的多个开发者的phpstorm连接,而DBGp Proxy也跟xdebug设置了remote_connect_back一样能自动获取与它相连接的phpstorm的ip(并且还会用IDE key区分,我猜是一台电脑上可能有两个phpstorm吧),DBGp Proxy的作用就是把远程的xdebug映射到内部有公网ip的服务器上,让phpstorm能连接它(事实上在以前xdebug还没有remote_connect_back参数时,即使xdebug所在服务器在局域网内,也需要DBGp Proxy来完成这个工作)。

关于多用户debug

Step Debugging中搜索“Multiple Users Debugging”即可看到如下内容
-w629

从上图内容可知,如果你要多用户同时debug(相互之间不影响),其实是有“two solutions”(两个解决方案)的,方式一是DBGp Proxy工具,方式二是设置xdebug.remote_connect_back=On(或等于1都行),显然方式二更简单,方式一只有在远程多用户调试时可能用的到。

设置不需要debug的php文件

在Preferences/Settings→Languages & Frameworks→PHP→Debug→Skipped Paths 中添加你不想它参与debug的单个文件或整个文件夹
-w981

开始debug

“PHP Web Page”本地Debug

  • 1.在php.ini中添加xdebug相关配置,注意xdebug.remote_host="127.0.0.1"(注意重启php-fpm);
  • 2.在phpstorm中修改Debug port,保证它与php.ini中的xdebug.remote_port值相同;
  • 3.在phpstorm中添加要debug的网站
  • 4.在phpstorm中添加PHP Web Page配置,其中Server填写前面添加的网站
  • 5.在phpstorm中点击“小电话”图标开启监听端口(这样xdebug才能往该端口发送数据);
  • 6.在phpstorm中添加断点(编辑器行号旁边点一下就会添加一个断点);
  • 7.在浏览器中使用浏览器插件(如Xdebug Helper)或在URL中添加XDEBUG_SESSION_START=xxxx这样的参数来告诉xdebug你要开启debug;
  • 8.运行代码,比如刷新浏览器或点击浏览器上的某个按钮(即使是ajax请求的按钮也行,只要这个请求最终能运行到你打断点的那一行代码),如果一切正常,则此时phpstorm会被自动调出,断点行会高亮显示,断点相关的变量也会显示在phpstorm下方的控制台中;

-w1440

“PHP Web Page”局域网远程Debug

“PHP Web Page”外网远程Debug

“PHP Remote Debug”本地Debug

  • 1.在php.ini中添加xdebug相关配置,注意xdebug.remote_host="127.0.0.1"(注意重启php-fpm);
  • 2.在phpstorm中修改Debug port,保证它与php.ini中的xdebug.remote_port值相同;
  • 3.在phpstorm中添加要debug的网站
  • 4.在phpstorm中添加PHP Remote Debug配置,其中Server填写前面添加的网站
  • 5.在phpstorm中点击“小电话”图标开启监听端口(这样xdebug才能往该端口发送数据);
  • 6.在phpstorm中添加断点(编辑器行号旁边点一下就会添加一个断点);
  • 7.在浏览器中使用浏览器插件(如Xdebug Helper)或在URL中添加XDEBUG_SESSION_START=xxxx这样的参数来告诉xdebug你要开启debug;
  • 8.运行代码,比如刷新浏览器或点击浏览器上的某个按钮(即使是ajax请求的按钮也行,只要这个请求最终能运行到你打断点的那一行代码),如果一切正常,则此时phpstorm会被自动调出,断点行会高亮显示,断点相关的变量也会显示在phpstorm下方的控制台中;
  • 9.不要从“PHP Remote Debug”这个名字上认为它只能用于远程debug,其实它也可以用于本地,从根本上来说,远程和本地并没有区别,特别是局域网远程,无非就是ip是127.0.0.1还是192.168.xx.xx的区别;

“PHP Remote Debug”局域网远程Debug

“PHP Remote Debug”外网远程Debug

命令行方式执行网站代码(本地debug)

  • 1.在php.ini中添加xdebug相关配置,注意xdebug.remote_host="127.0.0.1"(注意重启php-fpm);
  • 2.在phpstorm中修改Debug port,保证它与php.ini中的xdebug.remote_port值相同;
  • 3.在phpstorm中点击“小电话”图标开启监听端口(这样xdebug才能往该端口发送数据);
  • 4.在phpstorm中添加断点(编辑器行号旁边点一下就会添加一个断点);
  • 5.在终端工具中执行以下命令设置XDEBUG_CONFIG变量
# Mac/Linux
export XDEBUG_CONFIG="idekey=PHPSTROM"
# Windows
set XDEBUG_CONFIG="idekey=PHPSTROM"
  • 6.在刚才设置了变量的那个终端界面里面里执行代码:php /path/to/test.php就会开启debug(自动弹出phpstorm),而会开启debug的原因就是因为前面设置了XDEBUG_CONFIG变量。
  • 7.注意:命令行方式执行本地代码,不需要在phpstorm中添加要debug的网站,也不需要添加debug配置,所以下图这里你无论选什么,它都一样能debug(因为跟这个压根无关,这个是网站形式debug用的)
    image.jpg

命令行方式执行网站代码(局域网远程debug)

  • 1.在php.ini中添加xdebug相关配置,注意要设置xdebug.remote_host="你的电脑ip"(命令行方式执行php,xdebug.remote_connect_back=On这个配置是不生效的,所以只能设置xdebug.remote_host为你电脑的ip,所以只能单人调试,多人无法调试,最后注意重启php-fpm);
  • 2.在phpstorm中修改Debug port,保证它与php.ini中的xdebug.remote_port值相同;
  • 3.在phpstorm中添加要debug的网站
  • 4.在phpstorm中点击“小电话”图标开启监听端口(这样xdebug才能往该端口发送数据);
  • 6.在phpstorm中添加断点(编辑器行号旁边点一下就会添加一个断点);
  • 7.在终端工具中ssh登录到你要debug的php代码所在的服务器,然后执行以下命令设置XDEBUG_CONFIG以及PHP_IDE_CONFIG两个变量(比在本地多一个PHP_IDE_CONFIG变量,且PHP_IDE_CONFIG的值要设置为第3步中添加的网站域名,具体原因看这里)
# Mac/Linux
export XDEBUG_CONFIG="idekey=PHPSTROM"
export PHP_IDE_CONFIG="serverName=www.example.com"
# Windows
set XDEBUG_CONFIG="idekey=PHPSTROM"
set PHP_IDE_CONFIG="serverName=www.example.com"
  • 8.在刚才设置了变量的那个终端界面里面里执行代码:php /path/to/test.php就会开启debug(自动弹出phpstorm),而会开启debug的原因就是因为前面设置了XDEBUG_CONFIG变量,并且还根据PHP_IDE_CONFIG变量在phpstorm中找到你设置的Servers中的映射,在本地找到对应文件。

命令行方式执行网站代码(外网远程debug)

  • 1.在phpstorm所在机器运行ssh命令建立ssh远程端口转发(反向隧道)
  • 2.所有其它步骤与命令行方式执行网站代码(本地debug)基本相同(因为ssh隧道已经把远程机器映射到本地,所以就相当于本地debug了);
  • 3.第2步中说基本相同,说明还是有不同,这个不同点是,要在终端中多设置一个变量(本地的只有XDEBUG_CONFIG变量,现在远程要多设置一个PHP_IDE_CONFIG,原因请看这里):
export PHP_IDE_CONFIG="serverName=www.example.com"

PHP Script debug

添加debug配置里,只讲了“PHP Web Page”和“PHP Remote Debug”,但还有一个是“PHP Script”,这个怎么用?

这个是真的不用任何配置的debug了,添加断点后,你只需要在编辑器界面上右击→Debugxxx.php (PHP Script)即可开始debug(在这之前任何配置都不用添加),连监听都不用开启(没错,你不需要像前面那些调试那样点击小电话监听端口)
-w1172

并且它会自动创建一个“PHP Script”配置(这不是我手动创建的,而是自动创建的)
-w1071

事实上,它只不过是用php去执行php脚本,并添加了一些选项,让它会使用xdebug来调试而已
image.jpg

当然这个一般只适合单文件,比如你只是用php来写一些纯命令行的代码(例如纯命令行代码是没有$_SERVER这种变量的),就可以用这种方式调试。


本文写的时候都是亲自试验得出的结果,并非直接搬运网上的内容,但由于文章内容较多,可能有些地方写错了,如有发现请评论指出,我将第一时间修正!

相关参考:
SSH远程端口转发
Step Debugging
Remote debugging via SSH tunnel
Configure path mappings(command line)
boolean xdebug.remote_connect_back = false
Xdebug作者在2009年写的文章:Debugging with multiple users

打赏
订阅评论
提醒
guest

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据

3 评论
内联反馈
查看所有评论
Bear
Bear
3 年 前

看了这么多文章,就这篇有用!

xin_qing_happy
xin_qing_happy
4 年 前

使用外网单用户开发的时候遇到一个问题,当我使用ssh端口转发来监听服务器的xdebug端口之后,我本地开启xdebug,此时访问未监听的页面全部不能访问

最后由xin_qing_happy编辑于4 年 前
George
George
4 年 前

博主也是phper,还希望多跟你学习学习,博文写的真好

3
0
希望看到您的想法,请您发表评论x

扫码在手机查看
iPhone请用自带相机扫
安卓用UC/QQ浏览器扫

可能是全网最详细的PhpStorm+xdebug远程调试php代码的教程