think-swoole是ThinkPHP适配Swoole的胶水层,不改变Swoole底层,但接管请求生命周期、重写容器/事件/会话逻辑;其入口为php think swoole,启动的是继承自Swoole\Http\Server的HttpServer类,覆盖onRequest回调交由TP应用处理。

ThinkPHP 的 Swoole 扩展(即 think-swoole)不是 Swoole 本身,而是为 ThinkPHP 框架适配 Swoole 运行环境的一层胶水——它不改变 Swoole 底层行为,但会接管请求生命周期、重写部分容器/事件/会话逻辑,稍有不慎就容易触发内存泄漏或协程上下文错乱。
think-swoole 和原生 Swoole Server 的启动方式差异
你不能把 think-swoole 当作一个独立的 Swoole 服务来写 Swoole\Http\Server 实例。它的入口是 php think swoole,底层调用的是封装好的 think\swoole\command\Swoole 命令类,最终启动的是 think\swoole\server\HttpServer ——这个类继承自 Swoole\Http\Server,但覆盖了 onRequest 回调,把请求交给了 ThinkPHP 的应用实例处理。
常见错误现象:
- 手动 new
Swoole\Http\Server并监听端口,再 require TP 入口,会导致路由、中间件、容器等全部失效 - 在
config/swoole.php中修改host或port后未重启服务,仍连旧端口 - 误以为
think-swoole支持 WebSocket 自动路由,实际需额外配置server_type为websocket,并手动注册onOpen/onMessage回调
config/swoole.php 中关键配置项的实际作用
这个配置文件不是“可有可无”的开关集合,而是直接影响进程模型和协程安全性的核心控制点:
立即学习“PHP免费学习笔记(深入)”;
-
enable:仅控制是否启用热更新,不影响服务是否运行;设为false时仍可正常启动 HTTP Server -
mode:必须与 Swoole 编译模式一致(SWOOLE_PROCESS或SWOOLE_BASE),TP6 默认用SWOOLE_PROCESS,若扩展编译为SWOOLE_BASE会导致WorkerStart事件不触发 -
task_worker_num:设为0时,defer和task方法将直接同步执行,失去异步意义 -
reload_async:设为true时,文件变更后 reload 不阻塞请求,但要求所有全局变量/单例对象支持热替换,否则引发状态残留
TP6 + think-swoole 下的 Session 和 Cookie 处理陷阱
传统 PHP-FPM 中的 session_start() 在 think-swoole 中完全失效——因为 Swoole 是常驻进程,PHP 内置 session 扩展依赖 CGI 生命周期,无法复用。
实际处理方式:
- Session 默认退化为基于
cache驱动的内存存储(如File或Redis),由think\swoole\session\Manager统一管理 - Cookie 不再通过
setcookie()发送,而是由响应对象在send()阶段统一注入 Header,所以中间件中调用response()->cookie()才有效 - 若在协程中使用
$_SESSION全局变量,会跨请求污染,必须改用app('session')获取当前请求绑定的会话实例
热更新(hot reload)为什么经常不生效
热更新依赖 inotify(Linux)或 fsevents(macOS),但 think-swoole 的检测逻辑只监控 include 配置路径下的 .php 文件,且默认排除 runtime/、vendor/、config/ 等目录。
容易被忽略的细节:
- 修改
config/app.php不触发 reload,因该文件在进程启动时已加载进内存,且未加入 watch 列表 - IDE 保存时生成的临时文件(如
xxx.php~)可能触发误 reload,建议在exclude中加入*~ - Windows 下默认禁用 inotify,需确认是否启用了 WSL2 或安装了
php-ext-win32service替代方案
真正影响稳定的从来不是配置多寡,而是协程上下文是否干净、全局状态是否可控——比如一个没 unset 的静态属性,在第 1000 次请求时才暴露出引用计数异常。



















