SwooleRuntime::enableCoroutine(SWOOLE_HOOK_ALL)必须在Worker进程启动前、onWorkerStart回调之前调用,推荐置于bin/hyperf.php入口顶部;重复调用无效且可能报错,可通过getHookFlags()和file_get_contents测试验证。

在 Hyperf 3.0 中,SwooleRuntime::enableCoroutine() 仍是最直接、最底层的协程 Hook 开关方式,但**调用时机和作用范围需特别注意**——它不能随意放在业务逻辑里,必须在 Swoole Server 启动前、且协程调度器尚未初始化时执行。
必须在 Worker 进程启动前调用
Hyperf 3.0 基于 Swoole 5+ 的协程 Server 模型,默认已自动开启协程环境,但 enableCoroutine() 的 Hook 行为(如让 file_get_contents、cURL、PDO 等同步函数协程化)不会自动生效。你需要显式调用,并确保它发生在:
- Hyperf 的
onWorkerStart回调之前 - 任何协程(
go)、HTTP 请求或定时器触发之前 - 通常放在
bin/hyperf.php入口或自定义启动脚本的最顶部
推荐写法:传入 SWOOLE_HOOK_ALL
Hyperf 场景下常见 I/O 操作(MySQL、Redis、HTTP 客户端、文件读写)都依赖完整 Hook,建议使用全量标志:
SwooleRuntime::enableCoroutine(SWOOLE_HOOK_ALL);
这会启用包括流、Socket、cURL、OpenSSL、MySQLi、PDO、Files 等在内的全部支持项。若只用部分功能(如仅 HTTP 客户端),可按需组合,例如:SWOOLE_HOOK_CURL | SWOOLE_HOOK_FILE。
不建议在 onWorkerStart 中重复调用
虽然 onWorkerStart 是常见配置入口,但此时协程调度器可能已初始化,重复调用 enableCoroutine(true) 无效,甚至引发警告。正确做法是:
- 在
bin/hyperf.php中,在HyperfContractApplicationInterface::start()之前调用 - 或在
config/autoload/server.php的callbacks中配置onStart回调(Swoole 层级) - 避免在
onWorkerStart或请求回调中调用
验证是否生效
可在任意协程上下文中检查 Hook 状态:
var_dump(SwooleRuntime::getHookFlags()); // 应返回非零整数,如 16383(SWOOLE_HOOK_ALL 对应值)
再测试一个典型同步函数是否协程化:
go(function () {
$start = microtime(true);
file_get_contents('https://httpbin.org/delay/1'); // 若已 Hook,不会阻塞其他协程
echo 'done in ' . (microtime(true) - $start) . "s
";
});
若耗时接近 1 秒且未影响同批其他协程运行,则说明 Hook 成功。











