hyperf 废除 $_session 是因协程共享内存导致会话污染,必须通过构造注入 sessioninterface 获取协程隔离的会话实例,其 set/get/migrate/invalidate 等方法确保线程安全与语义清晰。

Hyperf 为什么不能用 $_SESSION
因为 $_SESSION 在协程环境下是全局、共享、非隔离的,而 Hyperf 基于 Swoole 协程常驻内存运行。多个请求(协程)共用同一块进程内存,如果都往 $_SESSION 这个数组里写数据,必然发生覆盖或读错——比如张三刚 set('user', 'A'),李四紧接着 set('user', 'B'),张三后续 get 就拿到 'B',直接越权。
这不是 Hyperf “不支持”,而是主动废除:它把这种危险的隐式状态暴露为编译期/运行期错误,强制你改用线程安全的方案。
必须通过 SessionInterface 获取会话对象
Hyperf 的会话对象是协程上下文隔离的,每次请求都会从 DI 容器中解析出一个专属实例,背后由 SessionManager 按协程 ID 绑定存储空间。你拿到的 $session 只对当前请求有效,不会被其他协程干扰。
创建全面的交接文档,使新AI代理能够无缝继续工作,消除歧义。解决上下文耗尽问题。 时机:(1)用户请求保存交接,(2)上下文即将满,(3)主要任务完成,(4)会话结束,(5)恢复工作时。 关键词:保存状态、创建交接、上下文已满、暂停、从...恢复、加载交接、保存进度、会话转移、交接
- 必须用构造函数注入或
@Inject()注解声明:private SessionInterface $session - 不能在类属性上直接赋值或全局缓存该对象,否则会跨协程污染
- 不能在非 HTTP 生命周期(如定时任务、WebSocket 回调)中直接复用 HTTP 请求的
$session,需手动传入或重建上下文
SessionInterface 常用方法与陷阱
接口提供的是语义清晰、不可绕过的操作集合,没有魔术方法,也不允许直接访问底层数组:
-
set($key, $value):值会被序列化后存入 Redis/文件,$value必须可序列化(不能含闭包、资源句柄) -
get($key, $default = null):不抛异常,返回null表示键不存在,别用isset($session->get('x'))判断 -
migrate(true):登录后务必调用,销毁旧 ID 并生成新 ID,防会话固定攻击 -
invalidate():清空并删除当前会话,但 Cookie 不会自动过期,需配合前端清除或设置cookie_lifetime=0 -
getId()返回的是字符串 ID,不是数组索引;isValidId()是校验工具,不是会话是否活跃的判断依据
Redis 驱动下 session 过期逻辑容易被忽略
Hyperf 的 session 过期由两层控制:Cookie 自身有效期(cookie_lifetime)和 Redis 中 key 的 TTL(gc_maxlifetime)。两者不一致会导致“用户还能发请求但拿不到数据”或“Cookie 没过期但服务端已删 session”。
最稳妥的做法是让两者一致,并启用 Redis 的惰性删除 + 定期扫描机制。另外注意:expire 配置项只影响新写入 session 的 TTL,已有 key 不会自动刷新过期时间。










