php8.0+swoole4.x+yasd0.3.9+phpstorm 单元测试调试时附加 -e 参数
2022-12-20 解决方案
php8.1 以上配合swoole master分支代码 + xdebug,可进行调试
php8.1以下版本,可参考以下方案
前言
开发过程中免不了调试,相信大家调试时肯定不是一路的echo、var_dump、print等等吧, php调试一般是用xdebug来做,很成熟的产品了,调试过程很愉快,单步跟进、跳过分析业务逻辑等。
但是使用swoole后,因为它加了异步协程,所以不能用xdebug来调试了,应该用yasd, 但yasd一直没有发步正式版本。但差不多算是能用。
swoole配合yasd+phpstorm调试坑还是不少的。官方文档说是已经对vscode、phpstorm做了兼容,但实际使用下来简直是“车祸现场”,可能跟我使用方式有关吧,调试过程很不愉快。
启动调试要加-e参数,或加配置项,有些cli任务场景下会有影响
phpunit单元测试不兼容,官方文档有说明要加个协程启动入口,但无效果,代码里用到协程的,单元测试几乎是废的,跑不起来。
配置好后可断下来代码,但只要单步调试进入下一步就有一定几率崩溃,崩溃原因可能跟项目结构、代码逻辑等有关,已测试ubuntu20环境,docker+alpine16+php8.0镜像。
网络上 swoole调试相关的解决方案非常少,连提问的都不太多。遇到问题很难解决。
总之swoole是好东西,但和它配套使用的开发套件很少,导致开发成本、时间很高!也可能是还没掌握它的用法和精髓。如果有人有好的调试方案欢迎指正。
配置调试
yasd启动调试时需要加一个 -e 参数,如果直接在命令输入的话没什么问题,但如果在phpstorm配置运行时-e这个参数就没办法加了,因为phpstorm配置时默认是直接用php可执行文件所在路径,然后组合调试的一些参数来启动的,如下直接用/usr/local/bin/php
第一种方案:添加yasd的一个配置项,php启动时自动加-e参数
yasd.open_extended_info=1
另一种方案:可在php所在目录另外定义一个phpe 可执行文件并且默认加上-e 也执行命令,如下
phpe文件内容如下,注意里面路径换成自己的路径
#!/usr/bin/env sh /usr/local/bin/php -e "$@"
也可以添加一些环境变量来配合ide调试,如下添加serverName配置,让ide知道远程代码跟本本代码位置映射关系
#!/usr/bin/env sh # export XDEBUG_CONFIG="remote_enable=1 idekey=PHPSTORM remote_host=192.168.1.111 remote_port=9000 remote_autostart=1" export PHP_IDE_CONFIG="serverName=xxxxxx.loc" /usr/local/bin/php -e "$@"
添加到phpstorm中测试下,
因为phpstorm单元测试启动时默认添加的配置项为dxdubug_xxx开头的配置,所以还应该添加额外的yasd配置项,ip和端口分别是phpstorm所在机器ip和监听的端口
然后开启监听调试
在项目中下断点,执行单元测试就可以断下来了
最后提供一个自动识别项目来添加环境变量的脚本, 根据启动目录名称来添加对应的调试服务器域名
#!/usr/bin/env sh # 项目路径不正确的情况下,使用下面这一行 #projectPath=$(cd $(dirname $0);pwd) projectPath=$(pwd) # 从右往来取目录名 #projectName="${projectPath##*/}" # 通过/符号从左往右查询第二个目录名 projectName=`echo $projectPath | cut -d \/ -f 1` projectName=`echo $projectPath | cut -d \/ -f 2` projectName=`echo $projectPath | cut -d \/ -f 3` echo "projectPath:${projectPath}"; echo "projectName:${projectName}"; if [ "$projectName" = "xxxx" ]; then export PHP_IDE_CONFIG="serverName=xxxx.loc" fi /usr/local/bin/php -e "$@"
如果单元测试里有使用携程的东西,则还要加一个启动入口来初始化swoole环境,创建一个StartSwoole.php文件放在项目路径,tests/StartSwoole.php
<?php go(function () { global $argc, $argv; require __DIR__ . '/../vendor/bin/phpunit'; }); Swoole\Event::wait();
另外创建 phpunit.xml.dist 放到根目录,注意里面使用了上面创建的脚本来初始化swoole环境做为phpunit的入口
<?xml version="1.0" encoding="UTF-8"?> <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" backupGlobals="false" backupStaticAttributes="false" bootstrap="tests/StartSwoole.php" colors="true" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" stopOnFailure="false" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"> <testsuites> <testsuite name="Feature Tests"> <directory suffix="Test.php">./tests</directory> </testsuite> </testsuites> <logging/> </phpunit>
配置phpunit启动配置文件
后记:
实际使用中,有时会出现不能调试的情况,解决方法:先改成下面配置 /usr/local/bin/php,执行一次正常的单元测试,然后再改成/usr/local/binphpe 就可以了, 猜想是phpstorm更新了什么东西。
已知问题:
实际使用中查看变量会崩溃,需要ide下面debugger窗口来查看,并且达到一定深度也是崩溃,目前无解