PHP框架hyperf是cli方式执行,所以文件更改后需kill掉进程,再重新启动才能生效,但在Windows中开发,非常繁琐,本文记录关于hyperf框架的更改文件后自动重启的折腾之路。
首先说明开发环境,桌面环境为Windows,PHP运行环境在WSL中,开发工具为PHPstorm,我需要达到的目的是在Windows中更改项目文件后,hyperf会自动重启。
一、WSL直接监听Windows中项目目录文件
1、首先在WSL中安装inotify,用来监听文件变动。
apt-get install -y inotify-tools
2、添加监听文件变动的shell脚本,脚本暂时命名为hyperf_test_kill.sh
#!/bin/sh
# 监控排除.idea/runtime目录/.log/.swp文件
inotifywait -rq --exclude "(^.+.[^php]$)" -e modify /mnt/e/hyperf_test | while read LINE
do
kill -9 $(ps -ef | grep hyperf_test | grep -v grep | awk '{print $2}');
这个shell脚本是用来监听Windows中E盘下hyperf_test文件夹的变更,如果有变更,则kill掉项目进程
3、添加启动脚本,脚本暂时命名为hyperf_test__start.sh
#!/bin/sh # 清除缓存 rm -rf /mnt/e/hyperf_test/runtime/container; # 启动进程 php8.1 /mnt/e/hyperf_test/bin/hyperf.php start;
这个脚本是用来启动进程
4、安装supervisor常驻任务守护进程
apt-get install -y supervisor
5、添加常驻任务脚本
进入/etc/supervisor/conf.d/目录
添加hyperf_test_kill.conf
# kill hyperf_test进程 [program:hyperf_test_kill] directory=/root # 注意脚本路径 command=sh /root/hyperf_test_kill.sh autostart=true autorestart=true startsecs=1 startretries=50 redirect_stderr=true stdout_logfile=/var/log/supervisor/hyperf_test_kill.log user=root stdout_logfile_backups = 20
添加hyperf_test_start.conf
# 启动hyperf_test进程 [program:hyperf_test_start] directory=/root command=sh /root/message_start.sh autostart=true autorestart=true startsecs=1 startretries=50 redirect_stderr=true stdout_logfile=/var/log/supervisor/hyperf_test_start.log user=root stdout_logfile_backups = 20
添加完重新加载supervisor任务即可
但是这种发放在后来莫名其妙的不可用了,WSL中的inotify无法监听Windows的文件变更了,挂载磁盘也不行。
二、直接把项目克隆到WSL系统中
无法监听Windows后,另辟蹊径,直接把项目挪到WSL系统中,因为inotify只是无法监听Windows的文件变更,还是可以继续监听WSL系统的,并且kill进程和重启进程都很快。
但随之而来的问题是,在Windows中访问WSL文件太慢了,尤其是使用PHPstorm时,加载文件、读取索引等操作很是频繁,git切换分支也受到效率影响。
三、PHPstorm监听+inotify监听
在Windows中添加update.bat文件:
@echo off REM 启动WSL并执行Linux shell脚本 wsl sh /root/update.sh REM 执行完毕后关闭命令提示符窗口 exit
在WSL中/root目录下新增update.sh文件
#!/bin/sh echo "$(date '+%Y-%m-%d %H:%M:%S') - Updating log" >> /root/update.log;
hyperf_test_kill.sh脚本变更为:
#!/bin/sh
# 监控/root/update.log文件的变更
inotifywait -q -e modify /root/update.log | while read LINE
do
kill -9 $(ps -ef | grep bm_message | grep -v grep | awk '{print $2}');
done;
PHPstorm配置:

这套方法的逻辑是,在PHPstorm中使用File Watcher,文件保存时执行update.bat文件,update.bat会执行wsl sh /root/update.sh命令,而update.sh会往/root/update.log追加一条日志,使/root/update.log文件产生变动,inotify再监听update.log重启进程
四、终极解决办法
虽然过去两三年中一直在用hyperf和TP做开发,但一般都忙于开发业务,框架基本用法熟悉之后很少再看文档了。最近有个hyperf后台项目要做,使用的扩展包不兼容最新版的hyperf,需要修改的东西比较多,参考文档的地方比较多,无意中发现hyperf竟然早就支持热更新。
如果是基于swoole的hyperf框架,则直接使用hyperf/watcher包即可。
安装:composer require hyperf/watcher --dev
添加配置:php bin/hyperf.php vendor:publish hyperf/watcher
启动:php bin/hyperf.php server:watch
在wsl中,可以使用supervisor进行守护进程:[program:hyperf-skeleton-watch]
directory=/data/www/hyperf-skeleton
command=php bin/hyperf.php server:watch
autostart=true
autorestart=true
startsecs=1
startretries=50
redirect_stderr=true
stdout_logfile=/var/log/supervisor/hyperf-skeleton-watch.log
user=root
stdout_logfile_backups = 20
但如果使用的是swow的hyperf框架就比较麻烦了,只能使用buexplain/go-watch来进行热更新。这是一个golang的工具,所以必须先安装golang环境。
在wsl中安装好golang环境之后依次执行以下命令:
cd /data/wwwgit clone https://github.com/buexplain/go-watch.gitcd go-watchCGO_ENABLED=0 go build -o gowatch main.go
然后执行./gowatch run -h,出现帮助说明,即为安装成功。
启动:./gowatch run\
--preCmdIgnoreError=true\
--cmd "php"\
--args "-d extension=/usr/lib/php/20210902/swow.so, /mnt/e/dev/hyperf-swow-watch/bin/hyperf.php, start"\
--files "/mnt/e/dev/hyperf-swow-watch/.env"\
--folder "/mnt/e/dev/hyperf-swow-watch/app/, /mnt/e/dev/hyperf-swow-watch/config/"\
--autoRestart=true
此处对应的原始的php命令为php -d extension=/usr/lib/php/20210902/swow.so /mnt/e/dev/hyperf-swow-watch/bin/hyperf.php start
同样,我们在wsl中,可以使用supervisor进行守护进程:
[program:hyperf-swow-watch]directory=/data/www/go-watchcommand=/bin/bash -c './gowatch run --preCmdIgnoreError=true --cmd "php" --args "-d extension=/usr/lib/php/20210902/swow.so, /mnt/e/dev/hyperf-swow-watch/bin/hyperf.php, start" --files "/mnt/e/dev/hyperf-swow-watch/.env" --folder "/mnt/e/dev/hyperf-swow-watch/app/, /mnt/e/dev/hyperf-swow-watch/config/" --autoRestart=true'autostart=trueautorestart=truestartsecs=1startretries=50redirect_stderr=truestdout_logfile=/var/log/supervisor/hyperf-swow-watch.loguser=rootstdout_logfile_backups = 20