是,你这个怀疑很有根据。
更准确地说,不像是 “ThinkPHP 业务代码突然坏了”,而是升级到 Swoole 6.1.x/6.2 之后,curl/native
curl hook 在你这套 PHP 8.4.6 + Guzzle/Google SDK + gzip 组合下出现了兼容问题。think-swoole 可能
是触发入口,但根因更像在底层 Swoole hook。
我这样判断的原因是:
- 你已经用独立脚本复现了。不是跑 /movie 页面,不是走 ThinkPHP 控制器,而是单独的 tools/
debug_esearch_guzzle_swoole.php 在 hook_all 下就能拿到原始 gzip 字节;换成 hook_no_curl 或强制
Accept-Encoding: identity 就正常。这基本把问题指向了 Swoole 的 curl hook,而不是业务层。
- 项目里实际装的是 topthink/think-swoole v4.1.2,它在 Packagist 上声明支持 ext-swoole ^4.0|^5.0|
^6.0。所以“版本号上完全不兼容”这个结论并不成立,但“某条运行时路径有兼容问题”完全成立。
- Swoole 6.1 系列官方 release note 明确提到过多次 curl 相关调整:
- v6.1.0 提到兼容 PHP 8.4 的 curl 扩展
- v6.1.1 提到优化 curl 模块资源管理
- v6.1.2 提到继续适配 PHP 8.4 中 CURL 扩展的更新
这说明 6.1 这一代本身就在改 curl 相关底层,实现变化很大。你“升级后才出问题”的时间线和这个
非常吻合。
- think-swoole 自己并没有对 Guzzle/gzip 做特殊处理。它核心上只是启动时 Coroutine::set(...),然后
Runtime::enableCoroutine()。所以这类 gzip 解压异常,更像是 Swoole runtime hook 层的问题,不像
ThinkPHP 框架层的问题。
还有一个额外发现,得提醒你:
- 你项目的 config/swoole.php:81 里写的是 couroutine
- 但 think-swoole 读取的是 coroutine,见 vendor/topthink/think-swoole/src/concerns/
InteractsWithServer.php:60 和 vendor/topthink/think-swoole/src/concerns/WithContainer.php:37
这意味着你现在配置里的 hook flags 很可能根本没被读到,Swoole 实际上是在用
Runtime::enableCoroutine() 的默认行为。这个拼写问题不是当前 gzip bug 的根因,但如果后面要通过配
置关掉 curl hook,这里必须先修正,否则改了也不生效。
所以我的结论是:
- “升级 Swoole 导致”的概率很高。
- 但更精确的表述是:Swoole 6.1+/6.2 的 curl hook 在你这个组合里有回归/兼容问题。
- 这不太像 think-swoole 整体不兼容,更像 think-swoole 把 Swoole hook 打开后,踩中了 Swoole 6.x
的 curl 路径问题。
我没有找到一个上游 issue 明确写着“6.1.5/6.2 + Guzzle 返回原始 gzip 字节”,这一点是基于你本地复现
结果和 Swoole 6.1 的 curl 变更记录做的推断。但这个推断现在证据已经很强。
参考:
如果你要,我下一步可以不改业务代码,只给你两条最稳的方案对比:
- 回退到你之前稳定的 5.x
- 保持 6.x,但禁用 curl 相关 hook,只保留其它协程 hook
是,你这个怀疑很有根据。
更准确地说,不像是 “ThinkPHP 业务代码突然坏了”,而是升级到 Swoole 6.1.x/6.2 之后,curl/native
curl hook 在你这套 PHP 8.4.6 + Guzzle/Google SDK + gzip 组合下出现了兼容问题。think-swoole 可能
是触发入口,但根因更像在底层 Swoole hook。
我这样判断的原因是:
debug_esearch_guzzle_swoole.php 在 hook_all 下就能拿到原始 gzip 字节;换成 hook_no_curl 或强制
Accept-Encoding: identity 就正常。这基本把问题指向了 Swoole 的 curl hook,而不是业务层。
^6.0。所以“版本号上完全不兼容”这个结论并不成立,但“某条运行时路径有兼容问题”完全成立。
这说明 6.1 这一代本身就在改 curl 相关底层,实现变化很大。你“升级后才出问题”的时间线和这个
非常吻合。
Runtime::enableCoroutine()。所以这类 gzip 解压异常,更像是 Swoole runtime hook 层的问题,不像
ThinkPHP 框架层的问题。
还有一个额外发现,得提醒你:
InteractsWithServer.php:60 和 vendor/topthink/think-swoole/src/concerns/WithContainer.php:37
这意味着你现在配置里的 hook flags 很可能根本没被读到,Swoole 实际上是在用
Runtime::enableCoroutine() 的默认行为。这个拼写问题不是当前 gzip bug 的根因,但如果后面要通过配
置关掉 curl hook,这里必须先修正,否则改了也不生效。
所以我的结论是:
的 curl 路径问题。
我没有找到一个上游 issue 明确写着“6.1.5/6.2 + Guzzle 返回原始 gzip 字节”,这一点是基于你本地复现
结果和 Swoole 6.1 的 curl 变更记录做的推断。但这个推断现在证据已经很强。
参考:
如果你要,我下一步可以不改业务代码,只给你两条最稳的方案对比: