Webman中不能直接用session_start(),因其基于Workerman常驻内存多进程模型,PHP原生session依赖每次请求重载环境与文件存储,而$_SESSION在各Worker间完全隔离、无自动GC,导致集群下Session失效;必须通过Session::handlerClass()提前注册RedisHandler接管存储,并配置domain、secure等Cookie参数确保跨域正确传递。

Webman里为什么不能直接用session_start()启动Session
因为Webman基于Workerman常驻内存模型,PHP内置的session_start()依赖文件存储+请求生命周期,而Webman没有每次请求都重载PHP环境,$_SESSION在多进程间完全隔离,且不会自动触发GC或销毁逻辑。直接调用只会写入本地临时文件,其他Worker读不到,集群下必然失效。
必须显式替换底层存储驱动,让所有Worker进程统一读写Redis——不是“启用”而是“接管”。关键点在于:注册时机必须早于任何session_start()调用,否则中间件或路由已提前初始化了默认Handler。
- 不能在控制器里才调用
ini_set('session.save_handler', 'redis'),太晚了 - 不能依赖
config/session.php里的handler配置自动生效,Webman不走PHP原生Session启动链路 - 必须在
start.php或bootstrap/app.php中,通过Workerman\Protocols\Http\Session::handlerClass()硬编码指定类
怎么用RedisSessionHandler替代默认存储
Webman官方推荐使用Predis或phpredis扩展封装的RedisSessionHandler,但注意:它不是PHP内置的redis handler,而是Webman适配层封装,需手动注入。
示例代码(放在start.php顶部):
use Workerman\Protocols\Http\Session; use Webman\Session\Handlers\RedisHandler; // 必须在任何HTTP请求处理前执行 Session::handlerClass(RedisHandler::class); // RedisHandler会读取 config/session.php 中的 redis 配置 // 你只需确保 config/session.php 中有: // 'handler' => 'redis', // 'redis' => [ // 'host' => '127.0.0.1', // 'port' => 6379, // 'database' => 0, // 'password' => '', // 'prefix' => 'session:' // ]
-
RedisHandler内部使用hGetAll/hSet操作Hash结构,每个Session ID对应一个Redis key,字段为序列化后的$_SESSION数据 - 若Redis启用了密码,
password字段不能为空字符串,否则连接失败且无明确报错 -
prefix必须带冒号(如'session:'),否则和其他业务key冲突风险高
session.gc_maxlifetime在Webman里根本不起作用
PHP原生的session.gc_maxlifetime靠随机触发的垃圾回收机制清理过期Session,而Webman不运行PHP的GC流程——它把过期控制全交给Redis的EXPIRE命令。
所以你在php.ini或ini_set()里改这个值毫无意义。真正起效的是:config/session.php中的lifetime配置项(单位:秒),它会被RedisHandler用来设置每个key的TTL。
由 ReMe 驱动的记忆管理系统,支持跨会话记忆持久化、自动应用用户偏好以及智能上下文压缩...
- 默认是
1440(24分钟),远短于常见登录态需求,务必按业务调大,比如7200(2小时) - Redis本身不支持“滑动过期”,所以用户持续操作不会自动延长TTL;如需此行为,得自己在
write逻辑里重设EXPIRE - 不要在
session_destroy()后还依赖gc清理,RedisHandler::destroy()会直接del对应key,立刻生效
跨域或子域名下Cookie传递失败的典型表现
即使Redis Session共享成功,前端仍频繁掉登录,大概率是Set-Cookie没被浏览器正确携带回来。Webman默认生成的Cookie域是localhost或当前Host,不兼容api.example.com和www.example.com共用Session的场景。
修复方式在config/session.php中调整:
-
'domain' => '.example.com'(注意开头的点,表示匹配所有子域) -
'secure' => true(仅HTTPS传输,生产环境必须开) -
'http_only' => true(防XSS,别关) -
'same_site' => 'Lax'或'None'(后者必须配secure: true)
如果前端是Vue/React发请求,记得fetch加credentials: 'include',Axios加withCredentials: true,否则Cookie压根不发。
最易忽略的一点:Nginx反向代理时,如果没透传Host头或覆盖了X-Forwarded-Proto,Webman可能误判协议类型,导致secure Cookie被拒绝发送——检查$_SERVER['HTTPS']是否为on,而不是只看端口。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










