hyperf启动失败的三个硬性门槛是php版本≥8.1、swoole启用协程支持、首次启动前执行composer install --no-dev;否则会导致segmentation fault、class not found或静默无输出。

Hyperf 启动失败的三个硬性门槛
启动直接报 Segmentation fault、Class not found 或静默无输出,90% 是卡在这三件事没做对:
- PHP 版本必须 ≥
8.1—— 低于该版本,协程支持被跳过,后续所有功能形同虚设 -
php --ri swoole输出里必须有support coroutines: enabled—— 如果没有,说明加载的是旧版 Swoole(比如系统自带的非协程版),需确认extension=swoole.so指向的是 5.0+ 协程版 - 首次启动前必须运行
composer install --no-dev(生产环境)或至少composer dump-autoload(开发环境)—— 否则注解扫描器无法加载控制器类,@AutoController形同摆设
注解路由不生效?先查这三处配置
访问 /api/index 返回 404,但 config/routes.php 里写死的路由能通,说明注解链断了:
-
config/autoload/annotations.php中的'paths'必须显式包含你的控制器目录,例如:['app/Controller'];仅写['app']不够,Hyperf 不递归扫描子目录 - 开发时务必设
'cacheable' => false—— 开启缓存后改了注解不重启服务就无效,极易误判为“代码没生效” -
#[AutoController]和具体方法必须在同一个类中,且类名必须严格符合 PSR-4:文件名IndexController.php对应命名空间App\Controller\IndexController,错一个字母或大小写都不行
协程里不能用 sleep()、file_get_contents()、mysql_connect()
这些是同步阻塞调用,在协程环境中会挂起整个 worker 进程,导致并发能力归零甚至服务假死:
- 替代
sleep(1):用co::sleep(1)(注意是co::sleep,不是Coroutine::sleep) - 替代
file_get_contents($url):用Hyperf\HttpClient\Client实例的get()方法 - 数据库操作必须走
Hyperf\Database\Connection或 Eloquent ORM —— 直接调用 PDO 原生方法会复用连接句柄,引发MySQL server has gone away - 事务必须用
DB::transaction()包裹,手动beginTransaction()+commit()极易跨协程污染连接状态
go()、co()、Coroutine::create() 怎么选
三者都创建协程,但语义和使用习惯不同,混用容易埋坑:
-
co()是官方推荐的短名函数,语义最清晰(co= coroutine),且自动处理异常捕获和上下文继承,日常首选 -
go()功能等价,但部分老项目遗留代码较多,新项目建议统一用co() -
Coroutine::create()是底层静态方法,需手动传入callable,无额外封装,适合调试或极端定制场景,普通业务无需接触 - 切忌在协程内再嵌套
co()调用耗时 IO —— 多层协程调度开销明显,应优先用 Channel 或 Promise 组织并行逻辑
真正容易被忽略的不是语法,而是协程的“隐式共享”:每个协程有独立的上下文,但全局变量、静态属性、未隔离的单例对象仍会被所有协程共用。一次 var_dump($this->container) 可能看不出问题,但高并发下容器状态错乱才是最难复现的 bug 来源。











