如何在检测到代码变更时热重载CLI模式下的PHP进程?
CLI模式下PHP脚本实现热重载的几种方法
方法一:PHP原生代码实现文件监控+子进程重启
自己写监控脚本,通过轮询或监听文件变化自动重启业务脚本,适合不想依赖第三方工具的场景。
轮询版(兼容所有环境)
创建watch.php作为监控主脚本:
<?php // 要监控的业务脚本路径 $targetScript = './your_business_script.php'; $lastModifyTime = filemtime($targetScript); $childPid = null; // 启动初始子进程 function startChildProcess(string $script) { global $childPid; $childPid = pcntl_fork(); if ($childPid === 0) { require $script; exit; } } startChildProcess($targetScript); while (true) { clearstatcache(true, $targetScript); $currentModifyTime = filemtime($targetScript); if ($currentModifyTime !== $lastModifyTime) { echo "代码已更新,重启脚本...\n"; // 终止旧进程 if ($childPid) { posix_kill($childPid, SIGTERM); posix_waitpid($childPid, $status); } // 启动新进程 startChildProcess($targetScript); $lastModifyTime = $currentModifyTime; } sleep(1); // 调整轮询间隔,平衡性能和响应速度 } ?>
运行方式:php watch.php,之后修改your_business_script.php会自动重启。
高效版(依赖inotify扩展)
如果服务器安装了inotify扩展,可实现无轮询的实时监控,替换上面的循环部分:
<?php $fd = inotify_init(); inotify_add_watch($fd, $targetScript, IN_MODIFY); while (true) { $events = inotify_read($fd); if ($events) { echo "代码已更新,重启脚本...\n"; // 终止旧进程+启动新进程逻辑同轮询版 startChildProcess($targetScript); } } fclose($fd); ?>
方法二:借助命令行监控工具
用现成的文件监控工具配合PHP,无需写额外代码。
使用entr工具
- 安装entr:
- Ubuntu/Debian:
sudo apt install entr - macOS:
brew install entr
- Ubuntu/Debian:
- 运行命令:
find . -type f -name "*.php" | entr -r php your_business_script.php
该命令会监控当前目录下所有PHP文件,一旦有文件修改,自动重启业务脚本。
使用fswatch工具
- 安装fswatch:
brew install fswatch(macOS)或通过对应包管理器安装 - 运行命令:
fswatch -o . -e ".git" | xargs -n1 -I{} php your_business_script.php
-e ".git"用于排除git目录,避免无关文件触发重启。
方法三:基于Swoole框架的热重载
如果你的CLI脚本是基于Swoole开发的守护进程(如HTTP服务、WebSocket服务),Swoole自带热重载机制:
- 启动Swoole服务后,找到主进程ID
- 修改代码后,执行命令发送重载信号:
kill -USR1 主进程ID
也可以在Swoole配置中配合第三方工具开启自动监控,实现代码变更后自动触发重载。
注意事项
- 轮询模式的间隔不要设置过小,避免占用过多CPU资源
- inotify扩展需提前安装(
pecl install inotify) - 第三方工具需根据操作系统完成安装
- 热重载时注意保存业务数据,避免进程终止导致数据丢失
内容的提问来源于stack exchange,提问作者dsb
相关产品推荐
相关产品推荐

