ReactPHP 在 Yii2 中仅支持 CLI 场景,不可用于 Web 请求;需手动编写 Promise 链并弃用 ActiveRecord,正确方式是通过 yii\console\Controller 启动 Loop,避免混用同步组件。

ReactPHP 在 Yii2 里不能直接“异步运行控制器”
Yii2 是同步阻塞框架,reactphp/yii2-react 扩展不是给控制器加 async 关键字的魔法插件。它只提供一个 ReactPHP 事件循环的启动入口和基础集成胶水,真正的异步逻辑必须你自己用 React\EventLoop\Loop 或 React\Promise 显式编写,且不能混入 Yii2 的同步生命周期(比如不能在 beforeAction 里 await 一个 HTTP 请求)。
常见错误现象:PHP Fatal error: Swoole or ReactPHP loop already running,或请求卡死——因为你在 Web 请求中试图启动第二个 Loop;又或者写了 $loop->run() 后整个请求 hang 住,没意识到这会阻塞当前进程。
- 使用场景仅限于:CLI 命令(如
yii queue/listen)、长连接服务(WebSocket server)、定时任务触发器 - Web 请求响应阶段严禁调用
$loop->run();可接受的方式是把异步操作转为 Promise,在 CLI 或后台进程里 resolve - 该扩展不修改 Yii2 内核,不支持
yield或async/await语法糖,所有异步需手动链式处理
怎么正确启动 ReactPHP Loop 并接入 Yii2 CLI 命令
这是该扩展唯一稳定可用的场景:用 ReactPHP 替换传统轮询或 sleep 的 CLI 工具,比如监听 Redis 队列、轮询 API 端点、跑 TCP server。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 新建命令类继承
yii\console\Controller,在actionIndex()中获取React\EventLoop\LoopInterface实例(通过 Yii 容器或React\EventLoop\Factory::create()) - 用
$loop->addPeriodicTimer(1.0, function () { ... })替代sleep(1),避免阻塞 - 不要在 timer 回调里调用
$app->run()或任何 Yii2 Web 组件(如Yii::$app->db),它们不是线程安全的;改用原生 PDO 或React\MySQL\Connection - 示例片段:
$loop = \React\EventLoop\Factory::create(); $loop->addPeriodicTimer(5.0, function () use ($loop) { echo "tick at " . date('H:i:s') . "\n"; }); $loop->run();
为什么不能在 Yii2 Web 请求中“混合”ReactPHP 和 ActiveRecord
因为 yii\db\Connection 底层用的是 PHP 的 mysqli 或 PDO 同步驱动,它们会阻塞整个事件循环。你无法把 $user = User::findOne(123) 直接丢进 React\Promise\Promise。
常见错误现象:调用 React\MySQL\Connection 时抛出 Class 'React\MySQL\Connection' not found —— 这不是扩展问题,而是你漏装了 react/mysql,且它和 Yii2 的 DB 组件完全不兼容。
- 若真需要异步 DB,必须弃用
ActiveRecord,改用react/mysql或amphp/mysql等原生异步驱动 -
reactphp/yii2-react不提供任何数据库适配层,也不重写Query类 - 性能影响:强行包装同步调用(如用
React\ChildProcess\Processfork 子进程执行查询)反而更慢,还增加内存开销
composer require reactphp/yii2-react 后要检查三件事
这个包本身非常轻量,但依赖链容易出错,尤其在旧项目中。
- 确认已安装
react/event-loop:^1.4或^2.0(Yii2 2.0.x 项目推荐用^1.4,否则可能与symfony/polyfill-php80冲突) - 检查
config/web.php或config/console.php是否误加了'bootstrap' => ['react']—— 该扩展没有名为react的组件,加了会报Unknown component ID: react - 运行
php yii看命令列表是否出现react/start—— 如果没有,说明扩展未被正确注册,通常是因为vendor/reactphp/yii2-react/src/Bootstrap.php没被加载(检查 composer autoload 或手动 require)



















