php bin/hyperf.php start 不触发注解扫描,是因为该命令在生产环境默认跳过扫描阶段,原因包括:scan_cacheable 设为 false、runtime/container 缓存损坏、扫描目录权限不足或路径配置错误;必须改用 php bin/hyperf.php di:scan 手动强制扫描生成代理类缓存。

直接执行 php bin/hyperf.php start 无法生成代理类缓存,说明扫描阶段根本没跑起来——不是命令错了,是启动流程卡在了前置条件上。
为什么 start 命令不触发注解扫描
Hyperf 的注解扫描和代理类生成只发生在「容器初始化后、服务器监听前」的特定生命周期阶段。而 php bin/hyperf.php start 在生产环境默认跳过该阶段,原因有三:
- 配置中
scan_cacheable被设为false(常见于生产环境 config/autoload/scanner.php) - runtime/container 目录存在但内容损坏(比如部分 proxy 文件写入中断),框架检测到已有缓存后直接跳过重建
- 扫描目录权限不足或路径配置错误(如
paths指向空数组或不存在的 vendor 子目录)
手动触发扫描必须用 scan 命令
Hyperf 提供了专用命令来强制执行扫描并生成缓存,它绕过服务启动逻辑,只做一件事:反射、提取、写入。运行以下命令:
php bin/hyperf.php di:scan
这个命令会:
立即学习“PHP免费学习笔记(深入)”;
- 读取
config/autoload/scanner.php中的paths和ignore_annotations - 调用
Hyperf\Di\Scanner实例,逐个require_once类文件(非 autoload 加载) - 把结果写入
runtime/container/proxy/下的.php文件,例如ControllerProxy.php - 失败时会明确报出哪个类 parse 失败(比如语法错误、use 缺失、PHP 版本不兼容)
扫完仍不生效?检查三个硬性依赖
即使 di:scan 显示 success,代理类也可能不被加载,常见卡点:
-
runtime/container目录权限:Web 服务器用户(如 www-data)必须有读+执行权限,否则 include 失败,日志里会出现failed to open stream -
composer dump-autoload -o未执行:如果新增了类或改了命名空间,classmap 没更新,di:scan会漏掉这些类 - pcntl 扩展缺失(尤其 Swow 驱动下):ProcScanHandler 依赖
proc_open,某些容器镜像禁用了该函数,需改用PcntlScanHandler并确认pcntl_fork可用
生产环境部署时最容易忽略的一点
CI/CD 流程里常把 di:scan 放在构建阶段,但 runtime 目录被设为 volume 挂载后,容器启动时 runtime/container 又被清空——扫描结果丢了。正确做法是:在容器 entrypoint 中,先 chown runtime 目录,再 php bin/hyperf.php di:scan,最后 php bin/hyperf.php start。顺序错一个,缓存就白生成。



















