Hyperf 3.0 注解失效主因有四:1. runtime/container 目录权限不足致代理类生成失败;2. 未清理该目录导致注解变更不生效;3. Windows+Docker 下 Finder 漏扫文件;4. 错误使用 Doctrine 注解或 PHP 8 Attributes 语法不当。

注解不生效,先看 runtime/container 是否可写
Hyperf 3.0 的注解解析结果会编译进 runtime/container 目录下的代理类和容器定义中。如果 Swoole 进程用户(如 www-data)对该目录没有写权限,代理类生成失败,@Inject、#[Controller] 等注解就会静默失效——不报错,但依赖为 null 或路由完全不注册。
检查方式:
- 运行
ls -ld runtime/container,确认属主与 Swoole 进程用户一致(ps aux | grep swoole查进程用户) - 若属主是
root或开发账户,执行sudo chown -R www-data:www-data runtime(按实际用户调整) - 确保目录权限至少为
755;若仍报Permission denied,临时试chmod -R 775 runtime
必须清理 runtime/container 才能刷新注解
Hyperf 不会在热更新或 server:watch 中重新扫描全部注解并重写 runtime/container。哪怕你改了 #[GetMapping] 或新增了 #[Service],旧的容器定义仍会被直接加载,导致“改了没反应”。
清理操作必须显式执行:
-
rm -rf runtime/container—— 这是唯一有效动作,runtime/cache和runtime/proxy清理不能替代它 - 不要用
rm -rf runtime/*,否则会误删logs/,生产环境排查时日志丢失更难定位 - 清理后必须重启服务:
php bin/hyperf.php start(开发)或php bin/hyperf.php server:restart(生产)
Windows + Docker 下注解漏扫,不是缓存问题而是 Finder 行为异常
当项目目录下 PHP 类文件数 >60 且使用 Windows + Docker 时,Symfony\Finder 在挂载卷中遍历顺序不稳定,可能跳过靠后的文件(如 Bar.php),导致其上的 #[CustomAnnotation] 根本未被解析——此时清空 runtime 没用,因为“压根没扫到”。
验证与应对:
- 在
ReflectionManager::getAllClasses()中加var_dump(count($reflectionClasses)),对比预期类数 - 避免用
find runtime -mindepth 1 -delete,某些 Windows+Docker 组合因挂载权限问题会失败 - 改用显式清理子目录:
rm -rf runtime/container runtime/proxy runtime/cache - 长期方案:将大目录拆分,或在
config/autoload/annotations.php中缩小scan.paths范围,分批扫描
PHP 8 Attributes 写法错误,和缓存无关但表现像失效
Hyperf 3.0 彻底弃用 Doctrine 注解(@Controller),只识别 PHP 8 Attributes(#[Controller])。常见“失效”其实是语法写错:
-
public UserService $service;→ 缺少#[Inject],类型提示不触发注入 -
// @Inject public UserService $service;→ 注释不是注解,完全忽略 -
#[Inject] private UserService $service;→private属性无法被代理类注入,必须public或protected - 混合写法如同时存在
@Controller和#[Controller],hyperf/annotation-compat不保证兼容,建议全量替换
这类问题不会因清理 runtime 改变,必须修正代码本身。最稳妥的验证方式:删掉整个 runtime/,再启动,看日志里是否出现 Generate proxy for App\...。


















