不安全。Swoole协程中直接读写$_SESSION、$_GET、$GLOBALS等全局变量必然导致数据错乱,因协程共享进程内存且调度抢占式,无隔离机制;应使用Coroutine::getContext()或DI获取SessionInterface等协程隔离方案。

不安全。Swoole协程中直接读写 $_SESSION、$_GET、$_POST、$GLOBALS、类静态属性(如 User::$cache)、全局对象属性(如 $config->timeout)等,必然导致数据错乱。
为什么协程里用全局变量会出问题
协程共享同一进程内存空间,但调度是抢占式的。一个协程在修改全局变量的中途,CPU 可能切到另一个协程,后者也去改同一个变量——没有锁、没有隔离,结果就是谁最后写谁赢。
- 协程 A 设置
$_SESSION['user_id'] = 1001,刚写完还没读,就被挂起 - 协程 B 进来把
$_SESSION['user_id']改成2002 - 协程 A 恢复执行,读到的却是
2002,用户身份彻底串了 - 这种污染不是偶发,只要并发 ≥2 就稳定复现
哪些写法看起来“像局部”实则危险
表面看没动全局,但底层仍指向共享内存,一样踩坑:
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
- 用
use (&$var)引入外部变量:引用传递的是原始地址,多个协程共用同一块内存 - 在
go()回调里直接赋值类静态数组:Cache::$data[$key] = $val——Cache::$data是进程级单例 - 把
$_SERVER或$_ENV当作只读上下文缓存:它们虽不常写,但某些中间件或扩展可能动态修改,不可信
协程安全的数据存放方式
必须依赖 Swoole 提供的协程隔离机制,而不是 PHP 原生变量作用域:
- 用
Coroutine::getContext()存取当前协程私有数据:$ctx = Coroutine::getContext(); $ctx['user_id'] = 1001; - Hyperf 用户必须通过 DI 获取
SessionInterface,不能碰$_SESSION—— 它背后是按协程 ID 隔离的存储池 - 需要跨协程通信时,用
Swoole\Coroutine\Channel或WaitGroup,别靠全局变量“传值” - 连接池(如数据库/Redis)本身已做协程隔离,但池外的手动连接(如 new PDO)仍是全局共享,严禁复用
最易被忽略的一点:即使你代码里没显式写全局变量,框架或 Composer 包里的静态缓存、单例日志器、全局配置对象,也可能在协程间悄悄污染数据。上线前务必检查所有第三方组件是否声明支持协程安全。

















