hyperf修改代码不生效主因是热更新未覆盖路径或注解缓存未重建:watch.dir需显式添加自定义目录(如base_path . '/app/http/controller'),且必须重启server:watch;注解变更须执行di:init-proxy重建runtime/container/annotation/缓存,枚举类注解热更新失效时需改用server:start加kill -usr1 reload。

Hyperf 修改代码后不生效,90% 是热更新没起作用或注解缓存没清掉 —— 不是代码写错了,而是框架根本没重新加载你改的文件。
server:watch 启动后改代码没反应?检查 watcher 配置路径
默认只监控 app 和 config 目录,如果你的控制器在 app/Http/Controller、服务在 app/Domain/User 或用了自定义命名空间(比如 MyApp),这些路径必须显式加进 config/autoload/watcher.php 的 watch.dir 数组里:
- 路径必须用正斜杠,
app\Http\Controller(Windows 反斜杠)会失效 - 不要写相对路径如
'app/Controller',要用BASE_PATH . '/app/Http/Controller' - 修改完配置后,必须重启
server:watch,它不会热重载自己的配置
注解类(如 #[Controller])改了但路由 404?先跑 di:init-proxy
Hyperf 3.0+ 使用注解扫描生成代理类和元数据,这些内容缓存在 runtime/container/annotation/ 下。即使你开了热更新,server:watch 也不会自动触发重新扫描 —— 它只负责重启进程,不负责重建 DI 容器。
- 首次添加新控制器、修改
scan.paths、或删过runtime/container/后,必须手动运行:php bin/hyperf.php di:init-proxy - 如果
SCAN_CACHEABLE=true(默认开启),但runtime/container/annotation/下没有生成文件,注解就静默失效,无任何报错 - Docker 构建时,确保
.dockerignore没过滤runtime/,且启动脚本不要rm -rf runtime/container
PHP 8 枚举类上的 #[OA\Property] 注解热更新失效?停掉 server:watch
这是已知限制:Hyperf 的 server:watch 对枚举(enum)结构的元数据重载不完整,尤其当修改的是嵌套在 case 上的属性注解(如 OpenAPI 的 #[OA\Property])时,旧缓存会卡住。
- 临时方案:停掉
server:watch,改用php bin/hyperf.php server:start启动 - 改完代码后,发送信号触发 reload:
kill -USR1 $(cat runtime/hyperf.pid) - 这不是 bug,而是 Watcher 组件当前未覆盖枚举反射变更的生命周期,官方暂未修复(截至 2026 年 5 月)
改了模型或缓存注解(如 #[Cacheable])但行为没变?注意 runtime 缓存残留
模型缓存、AOP 切面、注解代理类都依赖 runtime/container/ 下的 PHP 文件。哪怕你清了 OPcache,只要这些文件没更新,旧逻辑就还在跑。
- 最稳妥做法:
rm -rf runtime/container/ && php bin/hyperf.php di:init-proxy - 别只删
runtime/cache/—— 它不影响注解解析,只影响业务缓存 - 如果用了
hyperf/model-cache,改了数据库字段后,必须重新生成模型:php bin/hyperf.php gen:model user,否则缓存键结构错位,查不到数据
真正麻烦的从来不是“怎么清缓存”,而是清哪一层、什么时候清、以及清完要不要重建元数据 —— Hyperf 的多层缓存(OPcache + annotation cache + model cache + AOP proxy)叠在一起,漏掉任意一层,改了也白改。










