最稳妥的集成方式是使用topthink/think-swoole扩展,它已封装请求生命周期、协程上下文和自动重连等关键逻辑;手动编写Swoole\Http\Server脚本易遗漏$_SERVER模拟、协程Hook及异常捕获,导致内存泄漏或请求丢失。

直接用 topthink/think-swoole 是最稳妥的集成方式,它已封装好请求生命周期、协程上下文、自动重连等关键逻辑;自己手写 Swoole\Http\Server 启动脚本容易漏掉 $_SERVER 模拟、协程 Hook、异常捕获等细节,上线后大概率出现内存泄漏或请求丢失。
确认 Swoole 扩展已启用且支持协程
不是装了就行,必须验证协程能力是否开启:
- 运行
php --ri swoole,检查输出中是否含coroutine => enabled;若为disabled,需重新编译 Swoole 并加--enable-coroutine参数 - PHP 版本建议 ≥ 8.0,7.4 虽可运行但部分协程 API(如
Swoole\Coroutine\MySQL)行为不一致 -
php -m | grep swoole只能说明扩展加载成功,不能替代--ri检查
安装 think-swoole 并注册服务
官方适配器不是可选插件,而是集成前提:
- 执行
composer require topthink/think-swoole,注意不要装swoole/swoole—— 它和topthink/think-swoole冲突 - 确保
config/service.php中已启用该服务:默认已包含think\swoole\Service::class,无需手动添加 - 若项目启用了多应用模式,需确认
app/multi.php中未禁用全局服务注册
启动 HTTP 服务时绕过 Nginx,但别跳过环境模拟
用 php think swoole:server 启动,而非自己写 Swoole\Http\Server 实例:
立即学习“PHP免费学习笔记(深入)”;
- 该指令会自动构造
$_SERVER数组(包括REQUEST_URI、SCRIPT_NAME等),缺失会导致 ThinkPHP 路由解析失败 - 配置项应写在
config/swoole.php,而非硬编码进启动逻辑;例如'worker_num' => 4必须设,否则默认为 1,压测时立刻瓶颈 - 别在
swoole.php配置里写'daemonize' => true—— ThinkPHP 的日志与异常处理器在守护进程下可能无法正常 flush
WebSocket 或 RPC 场景需额外补全事件回调
think-swoole 默认只处理 HTTP,WebSocket 和 RPC 需手动绑定事件:
- WebSocket:在
app/command/SwooleChat.php中,$server->on('open', ...)和$server->on('message', ...)必须显式设置,框架不代劳 - RPC:需在
config/service.php中启用think\swoole\rpc\Service::class,并单独配置rpc键,仅靠 HTTP 配置无效 - 所有自定义
on*回调里,禁止直接调用echo或var_dump—— 协程环境下会阻塞整个 worker 进程
最容易被忽略的是数据库连接复用问题:Swoole 进程常驻,PDO 实例不会自动释放,必须在 onWorkerStart 里重建连接,或使用 Db::connect() 显式指定新连接,否则高并发下会报 MySQL server has gone away。



















