thinkphp6.0的session必须通过think\facade\session门面操作,禁用原生$_session和session_*函数;需在middleware.php中注册sessioninit中间件才能生效,否则set/get静默失败;支持点号嵌套赋值、flash(下请求有效)和pull(本请求即删),文件驱动时runtime/session目录须有写权限。

ThinkPHP6.0 的 Session 不是原生 PHP 的 $_SESSION,也不能调用 session_start() 或任何 session_* 函数——所有操作必须走 think\facade\Session 门面类或对应助手函数,否则会静默失败或报错。
Session 初始化必须加中间件
TP6 默认不启用 Session,哪怕你改了 config/session.php 也没用。关键一步是注册初始化中间件:
- 打开
app/middleware.php - 确保包含这一行:
\think\middleware\SessionInit::class - 如果用的是多应用模式(如
app/admin),且只在某个应用中需要 Session,就去对应应用的middleware.php里加,而不是全局文件
漏掉这步,Session::set() 看似执行成功,但数据根本不会写入、下次请求也读不到——因为底层 Store 实例压根没初始化。
Session::set() 和 Session::get() 的参数细节
Session::set() 支持点号语法写嵌套数据,但要注意它不是“自动创建数组”,而是按路径解析后直接赋值:
-
Session::set('user.name', '张三')→ 等效于$data['user']['name'] = '张三' -
Session::set('user', ['id' => 1])→ 会覆盖整个user键,之前设的user.name就没了 -
Session::get('user.name')可以安全取值;但如果user是字符串而非数组,会返回null(不报错) -
Session::get('missing', 'default')第二个参数才是默认值;不传则返回null,不是空字符串
别依赖 isset($_SESSION['x']) 这类判断——TP6 里它永远不存在。
闪存(flash)和 pull 的实际行为差异
Session::flash() 和 Session::pull() 都带“一次性”语义,但触发时机不同:
-
Session::flash('msg', '操作成功'):当前请求写入,**下一次 HTTP 请求时读取并自动删除**;适合重定向后展示提示 -
Session::pull('msg'):**本次请求内读取并立即删除**,不管是否重定向;适合表单提交后立刻清理临时状态 - 两者都依赖 Session 在请求结束时的自动保存机制;如果中途
exit或die,数据不会落盘
常见错误:在 AJAX 接口里用 flash 传提示,但前端没做重定向,导致提示“消失得莫名其妙”——这时该用 pull 或普通 get + delete。
文件驱动下 runtime/session 目录权限容易被忽略
当 type 设为 'file'(默认),Session 数据写到 runtime/session/ 下,但这个目录经常没写权限:
- Linux/macOS:运行
chmod -R 777 runtime/(开发环境可接受;生产环境建议chown给 web 用户) - Windows:检查目录属性 → “安全”页 → 确保 IIS_IUSRS 或对应用户有“修改”权限
- 如果权限不对,
Session::set()不报错,但Session::get()始终返回null,日志里也看不到明显异常
Redis 驱动虽然能绕过文件权限问题,但配置错 store 参数或连接不上 Redis 时,表现一模一样——所以排查 Session 失效,第一反应不该是“逻辑写错了”,而是先确认底层存储是否真正可用。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











