改 session 驱动为 database 前必须先运行 php artisan session:table 和 php artisan migrate 创建 sessions 表,确保 payload 字段为 text/longtext,并按环境变量>配置文件>默认值优先级设置 session_driver,同时校验 connection、table、session_secure_cookie 及 app_key 一致性。

Session 驱动改 database 之前必须确认 session 表存在
直接改配置不生效,最常见的原因是 Laravel 没有生成或迁移 sessions 表。Laravel 不会自动创建它,哪怕你已运行过 php artisan migrate —— 因为这个表不在默认迁移里。
- 运行
php artisan session:table生成迁移文件(Laravel 5.0+ 均支持) - 再执行
php artisan migrate,确保数据库中出现sessions表,字段含id、user_id、ip_address、user_agent、payload、last_activity - 如果手动建表,注意
payload字段必须是text或longtext,否则大 session 写入会截断或报错SQLSTATE[22001]: String data, right truncated
修改 SESSION_DRIVER 的三种方式及其优先级
不是改了 .env 就一定生效,Laravel 读取 session 驱动的顺序是硬编码逻辑:环境变量 > 配置文件 > 默认值。线上环境尤其容易踩坑。
-
.env中设SESSION_DRIVER=database是最常用方式,但需确认没有在config/session.php里硬编码覆盖了'driver' => 'file' - 若在代码里调用过
config(['session.driver' => 'database']),它会在运行时覆盖配置,但仅对当前请求有效,调试时容易误判 - 某些部署环境(如 Envoyer、Forge)可能缓存了配置,改完
.env后必须运行php artisan config:clear,否则旧驱动还在用
database 驱动依赖 connection 和 table 配置项
只改 SESSION_DRIVER 不够,config/session.php 里还有两个关键键值决定它连哪个库、查哪张表。
-
'connection' => null表示使用默认数据库连接;如果 session 要走单独的读库或小容量库,得显式设成'connection' => 'session_db',并确保该连接在config/database.php中已定义 -
'table' => 'sessions'可以改成其他名(比如加前缀),但必须和迁移出来的表名一致,否则写入时抛出SQLSTATE[42S02]: Base table or view not found - 注意:Laravel 9+ 对
payload字段做了 gzip 压缩,默认开启;如果用外部脚本读取 session 内容(比如后台查用户在线状态),得先解压,不然看到的是乱码二进制
切换后 session 丢失?检查 session.cookie.secure 和 HTTPS 环境
从 file 切到 database 本身不会导致丢失,但常伴随部署调整(比如上 Nginx + HTTPS),这时 cookie 属性不匹配会让浏览器拒绝发送 session ID。
- 如果站点启用了 HTTPS,但
SESSION_SECURE_COOKIE=true而服务器没正确传X-Forwarded-Proto,Laravel 会拒绝设置 Secure Cookie,导致每次请求都是新 session - 本地开发用
http://localhost却设了SESSION_SECURE_COOKIE=true,浏览器直接忽略该 cookie - 测试是否生效:登录后查看响应头
Set-Cookie是否带Secure和HttpOnly;再查数据库sessions表是否有新增记录,last_activity时间是否实时更新
database 驱动真正麻烦的不是配置,而是 payload 序列化/反序列化过程隐式依赖 APP_KEY —— 换密钥或跨环境同步 session 时,老数据会无法解密,表现为用户莫名登出。这事没法绕开,得提前想好密钥管理策略。











