php 调试指南(Xdebug版)

欢迎转载,但请在开头或结尾注明原文出处【blog.chaosjohn.com】

(吃透本文,没有人将比你更懂 Php Xdebug 调试

创建一个精简项目(命令行)

创建项目,并且用 composer 安装一个笔者比较喜欢的 微框架,作为示例

$ mkdir debug
$ cd debug
$ composer require mikecao/flight

编写主程序 index.php

cat >> index.php <

用 php 内置服务器运行项目

$ php -S localhost:8080
[Tue Dec  1 23:31:12 2020] PHP 7.4.13 Development Server (http://localhost:8080) started
[Tue Dec  1 23:31:35 2020] [::1]:57780 Accepted
[Tue Dec  1 23:31:35 2020] [::1]:57780 [200]: GET /
[Tue Dec  1 23:31:35 2020] [::1]:57780 Closing

php 调试指南(Xdebug版)_第1张图片
创建并且运行项目

上面输出的后三行,是在本机另一终端访问 http://localhost:8080 时打印的日志

$ curl -L localhost:8080
hello world!

(使用 php 内置服务器运行项目,只是为了检测项目是否能完好运行;该内置服务器只能用于开发环境,不能用于生产环境)

转移开发至 PhpStorm

JetBrains 公司出品的 PhpStorm 与其安装在此不做赘述。

PhpStorm 中打开项目

php 调试指南(Xdebug版)_第2张图片
PhpStorm 欢迎窗口选择“打开”

打开 偏好设置(mac下快捷键为 Command+, Win/Linux下快捷键为 Ctrl+Alt+s),左边侧边栏定位到 Languages & Frameworks => PHP

php 调试指南(Xdebug版)_第3张图片
打开 PhpStorm 偏好设置

在这里添加此前于 PHPBrew 中安装的 PHP 版本。参考前文 PHPBrew 使用指南(注意:请务必安装 xdebug 扩展:$phpbrew ext install xdebug,否则无法进行调试)

php 调试指南(Xdebug版)_第4张图片
添加 php 解释器

将刚刚添加上的 PHP 版本应用到当前项目


php 调试指南(Xdebug版)_第5张图片
选择 php 解释器

Nginx 运行项目

安装与管理

  • 无视系统环境 - 编译安装,不做赘述
  • macOS
$ brew install nginx
$ brew services start/stop/restart nginx # 启动/停止/重启 nginx
  • Debian / Ubuntu
$ sudo apt update
$ sudo apt install nginx-full
$ sudo systemctl start/stop/restart nginx # 启动/停止/重启 nginx
  • RHEL / CentOS
$ sudo yum update
$ sudo apt install nginx
$ sudo systemctl start/stop/restart nginx # 启动/停止/重启 nginx

配置(本文以 macOSHomebrewNginx 为例)

启动 php-fpm(用 PHPBrew 安装 PHP 时需要包含 +fpm variant)

$ phpbrew fpm start
Starting php-fpm...

在项目根目录下创建 nginx.conf 作为 Nginx 的配置文件

server {
    server_name localhost;
    listen 8000;

    root /Users/chaos/Work/php/demos/debug;

    location / {
        try_files $uri $uri/ /index.php;
        fastcgi_pass unix:/Users/chaos/.phpbrew/php/7.4.13/var/run/php-fpm.sock;
        fastcgi_index index.php;
        include fastcgi.conf;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

将该配置文件 软链接 到 Nginx 配置目录下 /usr/local/etc/nginx/servers/

$ ln -sf /Users/chaos/Work/php/demos/debug/nginx.conf /usr/local/etc/nginx/servers/php-debug.conf

检查 nginx.conf 是否有错误

$ nginx -t
nginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok
nginx: configuration file /usr/local/etc/nginx/nginx.conf test is successful

启动 Nginx

$ brew services start nginx
==> Successfully started `nginx` (label: homebrew.mxcl.nginx)
php 调试指南(Xdebug版)_第6张图片
Nginx 配置

终端下 curl 访问 Nginx部署的服务,验证项目成功跑了起来

$ curl -L localhost:8000
hello world!

Xdebug 调试

大部分关于 Xdebug 的配置,在前面部分已经配置完毕,我们来验证一下是否配置成功

PhpStorm 顶部菜单栏点击 Run,在下拉菜单中选中 Web Server Debug Validation,弹出窗口中点击底部的 Validate 按钮。

  • 如果显示成功,则调试环境已经搭建完毕
  • 如果显示出错,会给出排错信息


    php 调试指南(Xdebug版)_第7张图片
    出错,显示排错信息

发现三处警告,按照排错信息排查,发现问题出在了 Xdebug 3.0.0 版本变动了非常多的地方,导致目前 PhpStorm 最新的稳定版 2020.2.4 对此兼容性欠缺。不过 2020.3 有望解决。

所以笔者将 Xdebug 降级到了 2.X 版本:phpbrew ext install xdebug 2.9.8,再次点击 Validate 按钮,怎么还是一样的报错?

这里我们查看 php-fpm 的信息

$ phpbrew fpm info
...
xdebug support => enabled
Version => 3.0.0
...

所以需要重启一下 php-fpm,让其加载新的 Xdebug 模块

$ phpbrew fpm restart
Stopping php-fpm...
Starting php-fpm...
$ phpbrew fpm info
...
xdebug support => enabled
Version => 2.9.8
...

再次点击 Validate 按钮

php 调试指南(Xdebug版)_第8张图片
2.9.8 依旧报错

依旧报错,不过这里就清晰很多了,照着提示,phpbrew config 直接调用编辑器打开 php.ini 文件,在尾部添加:

[xdebug]
xdebug.remote_enable=1

phpbrew fpm restart 后再次点击 Validate 按钮,成功!

php 调试指南(Xdebug版)_第9张图片
Validate 成功

这就可以愉快的调试部署在 Nginx 里的项目啦,这里我们点击工具栏的 监听按钮,开始监听连接请求

php 调试指南(Xdebug版)_第10张图片
监听请求

浏览器作为请求客户端进行调试

为浏览器安装插件

  • Xdebug Helper for Firefox 源码
  • Xdebug Helper for Chrome 源码

这里笔者以 Chrome 浏览器为例,安装完后,右键 Xdebug Helper 图标点击 Options 打开选项页,选择 IDE keyPhpStorm

php 调试指南(Xdebug版)_第11张图片
Chrome 下 Xdebug Helper 配置

新开浏览器窗口,地址栏输入localhost:8000访问服务,页面会显示 hello world!。单击 Xdebug Helper 图标,点击 Debug,开启调试模式,至此,图标将会变成绿色(或者使用 Alt+Shift+X 快捷键快速开关 Debug 模式)

php 调试指南(Xdebug版)_第12张图片
切换 Xdebug Helper 到 Debug 模式

准备开始调试:

  1. 确保 PhpStorm监听 按钮已激活
  2. PhpStorm 中给需要调试的代码行打上断点
  3. 确保浏览器的 Xdebug Helper处于 Debug 模式,图标变为绿色
php 调试指南(Xdebug版)_第13张图片
调试准备

刷新浏览器页面,PhpStorm 监听到请求传入,同时浏览器请求处于 Pending 状态,挂起等待请求响应

php 调试指南(Xdebug版)_第14张图片
开始调试

在弹窗中选择完正确的 php 文件后,PhpStorm 就进入了调试模式,成功地停在了断点处,在这里可以查看当前的各项 变量 以及单步运行

php 调试指南(Xdebug版)_第15张图片
PhpStorm断点调试

点击调试窗口左侧的 Resume Program 按钮,程序从断点处恢复运行,至此,浏览器侧的请求收到了等待已久的响应,在窗口渲染出 hello world! 字样

命令行 或其他 请求客户端 发起调试

在实际的纯接口开发场景中,除了类似 localhost:8000 的简单请求,还有诸多带有复杂参数的请求,以及各种 http method 的请求(GET / POST / PUT / HEAD / DELETE / OPTIONS),仅仅通过浏览器地址栏进行发起调试并不能胜任。

开发人品平时发起请求测试,一般都选用 命令行工具(例如 curl / httpie)或类似 Postman 这样的专业请求调试客户端。

通过查阅Xdebug 官方文档,得知,浏览器的插件开启 Debug 模式,仅仅是给当前session增加了一个 Cookie: XDEBUG_SESSION=PHPSTORM

那就简单了,以 curl 举例的三种方式:

  • $ curl -H "Cookie: XDEBUG_SESSION=PHPSTORM" localhost:8000
  • $ curl --cookie XDEBUG_SESSION=PHPSTORM localhost:8000
  • $ curl -b XDEBUG_SESSION=PHPSTORM localhost:8000

Postman 也类似,不再赘述

至此,在 PhpStorm 调试部署在 Nginx 中的项目,杀青!

提出疑问

还记得前面有一张关于配置 php解释器 图么(重新搬运放在本段下方),里面明明配置了 Xdebug 的参数,而 Web Server Debug Validation 还是提示要去 php.ini 中添加 xdebug.remote_enable=1

php 调试指南(Xdebug版)_第16张图片
配置 php 解释器

JetBrains 肯定不会那么无聊,放置一个无用的配置项在这里。那这个配置项究竟对哪块地方生效呢?

PhpStorm 工具栏点击 Add Configuration,点击 + 号,选择 PHP Build-in Web Server,端口改为 8088 (或其他未被占用端口)

php 调试指南(Xdebug版)_第17张图片
PhpStorm 添加配置
php 调试指南(Xdebug版)_第18张图片
PhpStorm 完善配置

选择刚刚新建的 运行配置 php build-in server,点击右侧 绿色三角按钮,运行项目(同时确保 监听按钮 也已激活)

PhpStorm 运行配置

再次在命令行下执行:

$ curl -H "Cookie: XDEBUG_SESSION=PHPSTORM" localhost:8000

Bingo!!! PhpStorm 成功进入了调试状态并且停在了断点处!

发散 1: 在 PhpStorm 调试 远程服务

上文描述的都是调试本地环境,即服务部署在本地 Nginx,通过本地的 php-fpm 调用 php 解释器 进行请求分发处理,“加载”的是本地的 Xdebug(调试端口为默认的 9000),而同时 PhpStorm 也监听本地的 Xdebug9000 端口进行拦截调试。

可往往更多的情况是,服务并不部署在本地,而在 远端服务器,这个时候得如何调试呢?

接下来在 另一台主机(192.168.1.101) 上调试 本机(192.168.1.100) 的服务,来模拟现实开发中的 远程调试

本机(192.168.1.100) 上在 php.ini 尾部添加 xdebug.remote_connect_back=1

另一台主机(192.168.1.101)PhpStorm 点击工具栏上的 监听按钮 开启监听,并且在代码窗口设置断点

该主机(192.168.1.101) 的终端上执行

$ curl -H "Cookie: XDEBUG_SESSION=PHPSTORM" 192.168.1.100:8000

即可看到 PhpStorm 进入了调试模式并且顺利停在了断点处。

发散 2:在 VSCode 中调试 本地服务

打开 VSCode,安装 PHP Debug 扩展

打开项目工程,点击左边栏的 Run,点击 Create a launch.json file,选择 PHP 环境

php 调试指南(Xdebug版)_第19张图片
创建 VSCode 运行配置

VSCode 将会自动创建两个配置:

  • Listen for XDebug:这个配置就是类似 PhpStorm 中的 监听按钮
  • Launch currently open script:执行按照 php-cli 模式运行/调试 当前窗口的php脚本
php 调试指南(Xdebug版)_第20张图片
VSCode 创建的默认运行配置

选择 Listen for XDebug 并点击左侧的 绿色图标 开始运行监听,并且打上断点,命令行下执行 curl --cookie XDEBUG_SESSION=VSCODE localhost:8000,则能看到VSCode 成功进入了调试状态并且停在了断点处。

php 调试指南(Xdebug版)_第21张图片
VSCode 调试模式

发散 3:在 VSCode 调试 远程服务

发散 1 类似,在 另一台主机(192.168.1.101) 上:

  • 确保 php.ini 已添加 xdebug.remote_connect_back=1
  • 选择 Listen for XDebug 并点击左侧的 绿色图标 开始运行监听,并且打上断点
  • 命令行下执行 curl --cookie XDEBUG_SESSION=VSCODE 192.168.1.100:8000 则能看到VSCode 成功进入了调试状态并且停在了断点处。

所以,在 VSCode 调试部署在 Nginx 中的服务(本地与远程),也顺利杀青!

一些 思考疑惑

  1. XdebugIDE key(即使在 php.ini 中配置了 xdebug.idekey=xxx)在 远程调试 时并不起作用,调试请求时在 Cookie 中附加的 XDEBUG_SESSION 设置任意非空字符串都生效。是 Xdebugbug 么?
  2. 无论采用 PhpStorm 还是 VSCode 进行远程调试中,明明远程服务器的 Xdebug 调试端口(默认为9000)对外不可达(仅 localhost 可访问),但是 打上断点 开启监听 又能调试了呢?
  3. 多人协同调试,参考 JetBrains 文档 Multiuser debugging via Xdebug proxies 使用 DBGp代理

你可能感兴趣的:(php 调试指南(Xdebug版))