Session通过PHPSESSID Cookie实现会话跟踪,数据序列化存储于服务器文件,依赖Cookie传递ID但可配置URL参数替代,GC机制按gc_maxlifetime清理过期文件,销毁分session_destroy()主动删除与GC被动回收,HttpOnly/Secure标志保障传输与访问安全。

一、Session的创建与ID分发机制
当用户首次访问启用session的PHP脚本时,服务器会生成一个唯一字符串作为Session ID,并通过HTTP响应头Set-Cookie指令发送至客户端浏览器。该ID被浏览器持久化存储为名为PHPSESSID的Cookie,后续请求自动携带此ID回传服务器,从而建立连续会话上下文。
1、执行session_start()函数,触发PHP内核初始化session模块。
2、检查$_COOKIE中是否存在PHPSESSID字段;若不存在,则调用session_id()生成随机字符串(如hfuaeua4134afavasf)。
3、向客户端响应头写入Set-Cookie: PHPSESSID=hfuaeua4134afavasf; path=/; HttpOnly; Secure(若启用HTTPS)。
立即学习“PHP免费学习笔记(深入)”;
4、在服务器端根据session.save_path配置路径,以PHPSESSID为文件名创建空session文件(如sess_hfuaeua4134afavasf)。
二、Session数据的序列化存储流程
PHP将$_SESSION超全局数组中的键值对进行serialize()序列化处理,并以纯文本形式写入对应session文件。该过程由内核在脚本执行结束前自动完成,确保数据落地不丢失。
1、向$_SESSION赋值:$_SESSION['name'] = 'ChenDasheng'; $_SESSION['age'] = 18;
2、PHP内部调用php_session_encode()对数组执行序列化,结果形如:s:4:"name";s:11:"ChenDasheng";s:3:"age";i:18;
3、打开session.save_path指定目录下的sess_XXX文件,执行flock()加锁防止并发写冲突。
4、将序列化字符串写入文件内容区,调用fflush()强制刷盘,随后释放文件锁。
三、Cookie的设置与客户端行为约束
Cookie由服务器通过setcookie()函数注入HTTP响应头,其生命周期、作用域及安全性均由参数显式控制。浏览器严格遵循RFC 6265规范解析并管理Cookie,任何输出前调用setcookie()均会导致Header already sent错误。
1、调用setcookie('user_token', 'abc123', time()+3600, '/', 'example.com', true, true);
2、检查响应头是否包含Set-Cookie字段,确认secure与HttpOnly标志已生效。
3、验证浏览器开发者工具Application → Cookies中是否出现对应条目,且Domain与Path匹配。
4、关闭浏览器后重新访问,观察Cookie是否仍存在——若未设expire参数则应消失,否则按max-age或expires时间保留。
四、Session与Cookie的依赖关系验证
Session机制默认依赖Cookie传递Session ID,但PHP允许禁用Cookie支持并改用URL参数传递。此时需手动在链接中附加SID,否则每次请求都会生成新会话,导致$_SESSION数据无法延续。
1、在php.ini中设置session.use_cookies = 0,重启Web服务。
2、执行session_start()后,检查$_SESSION是否为空数组;若为空,说明未关联已有会话。
3、启用session.use_trans_sid = 1,观察HTML输出中所有标签是否自动追加?PHPSESSID=xxx参数。
4、手动构造带SID的URL(如/index.php?PHPSESSID=hfuaeua4134afavasf),验证能否正确读取此前存入的$_SESSION数据。
五、Session文件的垃圾回收与失效判定
PHP内置GC(Garbage Collection)机制周期性扫描session.save_path目录下所有session文件,依据文件最后修改时间与session.gc_maxlifetime阈值比较,决定是否删除过期会话数据。该过程非实时触发,存在时间窗口偏差。
1、查看当前gc_maxlifetime值:echo ini_get('session.gc_maxlifetime'); // 默认1440秒(24分钟)
2、获取某session文件的mtime:stat /var/lib/php/sessions/sess_hfuaeua4134afavasf | grep Modify
3、计算当前时间戳减去文件mtime,若差值大于1440,则该文件在下次GC运行时被标记为可删除。
4、强制触发GC:修改session.gc_probability与session.gc_divisor使触发概率达100%,或直接调用session_gc()函数(PHP 7.4+)。
六、Session销毁的两种底层路径
Session销毁分为显式调用与隐式回收两类。session_destroy()直接清除服务器端session文件并重置$_SESSION为空数组;而GC机制则通过遍历文件系统被动清理,二者均不操作客户端Cookie。
1、执行session_start()后立即调用session_destroy(),确认session文件已被unlink()删除。
2、检查$_SESSION是否变为empty array,且后续对该数组赋值不再写入原session文件。
3、使用strace追踪PHP进程:strace -e trace=unlink,openat php -r "session_start(); session_destroy();",观察unlink系统调用是否命中对应sess_XXX路径。
4、对比未调用session_destroy()时,仅关闭浏览器导致的PHPSESSID Cookie失效——此时服务器文件仍存在,直至GC介入。
七、Cookie安全属性的强制生效验证
HttpOnly与Secure标志直接影响JavaScript访问能力及传输通道限制。未正确设置将导致XSS攻击下Cookie被盗取,或HTTP明文传输时Session ID被截获。
1、设置Cookie时明确传入HttpOnly与Secure参数:setcookie('auth', 'valid', 0, '/', '', true, true);
2、在浏览器控制台执行document.cookie,确认auth字段不可见——HttpOnly生效标志。
3、尝试在HTTP协议下访问页面,检查Response Headers中Set-Cookie是否缺失——Secure标志阻止非HTTPS环境写入。
4、使用curl -I http://example.com测试响应头,确认无Set-Cookie字段返回。



















