Hyperf 3.0 强制升级PHP 8.0+并全面转向原生Attribute注解,旧版@注释写法(如@Inject、@Controller)全部失效,必须改用#[Inject]、#[Controller]等语法,且需声明strict_types、正确设置Attribute作用域、删除AbstractAnnotation继承、构造函数参数带类型声明。

Hyperf 3.0 不是简单升级,而是 PHP 协程开发范式的正式确立——它强制要求 PHP 8.0+,全面弃用注释式注解,转为原生 Attribute,这意味着所有旧版 @Inject、@Controller 写法直接失效,不改就报错。
Hyperf 3.0 必须改的注解写法
Hyperf 2.x 的注释解析(如 @Inject)在 3.0 中已被移除,依赖 PHP 8.1+ 的原生 Attribute。不更新写法会导致容器无法识别依赖、路由注册失败、AOP 切面不生效。
- 旧写法(2.x):
@Inject、@Controller、@GetMapping等全部失效 - 新写法(3.0):必须用
#[Inject]、#[Controller]、#[GetMapping],且需声明declare(strict_types=1) - 类名空间要对齐:比如
Hyperf\HttpServer\Annotation\Controller已废弃,应改用Hyperf\HttpServer\Annotation\AutoController或直接#[Controller](注意命名空间是否已导入) - 自定义注解也得重写:若你封装过
@Cacheable这类注解,必须用#[Attribute]重新定义,并确保目标(AttributeTarget::CLASS | AttributeTarget::METHOD)正确
协程池配置不当直接拖垮服务
Hyperf 的异步任务、数据库查询、Redis 调用都跑在协程池里,但默认配置(max_connections => 10)只适合本地调试。线上高并发时,协程池瓶颈比数据库连接池更早暴露。
- 现象:接口延迟突增、
Coroutine::stats()显示coroutine_num持续接近max_coroutine、日志频繁出现"Wait timeout for connection" - 关键参数不是调大就行:
max_connections要结合业务平均耗时估算,比如单次 DB 查询平均 50ms,1 秒最多处理 20 次,那 100 并发至少需要 5 个连接;再乘以 Worker 数(默认 4),才得出合理值 -
wait_timeout设太小(如 0.1)会导致任务快速失败,设太大(如 10)会让请求卡死更久——建议设为业务最长容忍等待时间的 80% - Redis 和 MySQL 的协程池要分开配:不能共用同一组参数,
redis.pool.max_connections通常要比db.pool.max_connections大 2–3 倍(因 Redis 操作更快、连接复用率更高)
Hyperf 3.0 的异常捕获陷阱
协程环境下,try/catch 只能捕获当前协程内抛出的异常;一旦进到另一个协程(比如 go(function () { throw new Exception(); })),原始上下文就丢失了,不显式处理就会静默失败。
- 常见错误:在
#[AsyncTask]类里写try/catch,却没在execute()入口兜底,导致任务失败无日志、不重试 - 正确做法:每个协程入口(
go、co、execute())都应有独立try/catch,并主动调用Log::error()+throw触发重试机制 - 全局兜底要用
Swoole\Event::add()或Hyperf\ExceptionHandler\ExceptionHandler,但注意:它只捕获未被协程内catch的异常,不能替代业务层防御 - 别依赖
set_exception_handler:它在协程中不可靠,Swoole 会绕过它
Attribute 的语法细节、协程池的隐式依赖、异常传播的上下文断裂,这些点不亲手调一次、不看一眼 Coroutine::stats() 输出,很难建立直觉。



















