php session 数据默认存于服务器文件系统(如/tmp目录),每个session_id对应一个序列化$_session数组的文件;可通过session_save_handler切换为redis等存储。

PHP Session 的核心是通过服务端存储用户状态,配合客户端 Cookie 传递唯一标识(session_id),实现跨请求的上下文保持。面试中常考的不是“怎么用”,而是“为什么这样设计”“数据存在哪”“怎么保证安全”。
Session 数据存在哪里?
默认存在服务器文件系统(/tmp 目录下),每个 session_id 对应一个独立文件(如 sess_abc123...)。文件内容是序列化后的 $_SESSION 数组(用 serialize() 格式,非 JSON)。
CPWEB企业网站管理系统(以下称CPWEB)是一个基于PHP+Mysql架构的企业网站管理系统。CPWEB 采用模块化方式开发,功能强大灵活易于扩展,并且完全开放源代码,面向大中型站点提供重量级企业网站建设解决方案。CPWEB企业网站管理系统 2.2 Beta 测试版本,仅供测试,不建议使用在正式项目中,否则发生任何的后果自负。
可通过 session_save_handler 切换存储方式:数据库(MySQL/Redis)、Memcached、甚至自定义 handler。Redis 是高频替代方案——速度快、支持过期自动清理、天然适合分布式环境。
Session ID 怎么生成和传递?
- 首次访问时,PHP 调用 session_start() 自动生成 32 位十六进制字符串(基于加密随机数,如 /dev/urandom)
- 默认通过 Set-Cookie 响应头写入客户端,Cookie 名为 PHPSESSID(可由 session.name 配置)
- 后续请求中,浏览器自动带上该 Cookie;PHP 读取并匹配服务端对应文件,还原 $_SESSION
- 也可禁用 Cookie,改用 URL 参数(session.use_cookies=0 + session.use_trans_sid=1),但不推荐——不安全且影响 SEO
Session 安全关键点有哪些?
- 防止会话固定(Session Fixation):登录成功后必须调用 session_regenerate_id(true),销毁旧 session 文件并生成新 ID
- 防止会话劫持(Session Hijacking):启用 session.cookie_httponly=1(JS 无法读取)、session.cookie_secure=1(仅 HTTPS 传输)
- 避免会话泄露:不要在日志、URL、错误信息中打印 session_id;关闭 session.hash_function 的弱哈希(如 md5)
- 合理设置过期:session.gc_maxlifetime 控制服务端文件存活时间;客户端 Cookie 过期由 session.cookie_lifetime 决定(0 表示浏览器关闭即失效)
常见误区与调试技巧
- “session_start() 必须在输出之前调用”——本质是因它要发送 Set-Cookie 头,而 HTTP 头必须在 body 前发送
- $_SESSION 不是实时同步的:修改后需等脚本结束或显式调用 session_write_close() 才写入磁盘/Redis
- 调试时可用 session_id() 查当前 ID,session_status() 看是否已启动,ini_get('session.save_path') 查存储路径
- 并发写入问题:同一 session_id 的多个请求可能相互覆盖。高并发场景建议尽早调用 session_write_close() 释放锁










