Hyperf 的 MySQL 协程化依赖 Swoole 的 hook_flags 运行时替换,未启用 SWOOLE_HOOK_ALL 或提前初始化连接会导致同步阻塞;需确保 PHP 8.2+ 与 Swoole 5.1.1+ 兼容,并禁用 opcache.enable_cli。

因为 MySQL 客户端默认走的是 PHP 原生的 mysqli 或 PDO 同步阻塞调用,Hyperf 的协程化能力不会自动生效——它必须依赖 Swoole 的协程 Hook 机制来拦截并重写底层 IO 操作。
协程 Hook 是 MySQL 异步化的前提
Hyperf 本身不直接改写 MySQL 扩展行为。真正让 mysqli_query()、PDO::query() 变成非阻塞的,是 Swoole 在进程启动时通过 swoole_hook_flags 对系统函数做的运行时替换。如果没开启(比如配置里漏了、或被覆盖),所有数据库操作就退回到传统 PHP-FPM 模式:一个请求卡在 SQL 上,整个协程就挂起,后续任务无法调度。
常见未开启 Hook 的表现:
- 使用
Hyperf\DbConnection\Db连接 MySQL,但 QPS 上不去、并发一高就延迟飙升 -
Coroutine::stats()显示大量协程处于WAITING状态,且堆栈停留在 mysqli 或 PDO 调用处 - 明明启用了
enable_coroutine => true,但Co\run()内执行查询仍会阻塞其他协程
检查和启用 Hook 的关键位置
不是只看 config/autoload/swoole.php 里有没有 hook_flags,还要确认它是否被最终加载并生效:
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 确保
swoole.php中设置了完整 flag,例如:'hook_flags' => SWOOLE_HOOK_ALL & ~SWOOLE_HOOK_CURL(推荐先用SWOOLE_HOOK_ALL排查) - 检查是否在
bin/hyperf.php或server.php启动前,提前触发了 MySQL 连接(如配置文件里写了new \PDO(...)),这会导致 Hook 尚未生效就完成了同步初始化 - 运行
php -r "echo SWOOLE_HOOK_FLAGS . PHP_EOL;"确认常量定义正常;再用var_dump(swoole_hook_flags(SWOOLE_HOOK_ALL));测试是否可成功设置
Hyperf v3.2 的额外注意点
v3.2 要求 PHP >= 8.2,而部分旧版 Swoole 扩展(如 5.0.x 以下)对 PHP 8.2 的 Hook 支持不完整,可能导致 MySQL 相关函数未被正确拦截。建议:
- 升级 Swoole 至
5.1.1+(官方已明确修复 PHP 8.2 下的 mysqli/PDO Hook 兼容性) - 禁用 opcache 的
opcache.enable_cli=1(CLI 模式下开启可能干扰 Hook 注入) - 避免在
__construct或静态初始化块中直接执行数据库操作——应延至协程上下文内(如@OnWorkerStart回调或go()中)
本质上,Hyperf 不是“自带协程 MySQL”,而是提供了一套能与 Swoole Hook 协同工作的容器和连接池封装。没开 Hook,它就只是个更优雅的同步框架。










