Session 基础流程
<?php
// 1. 必须在任何输出前调用
session_start();
// 2. 读写 $_SESSION 超全局数组
$_SESSION['user_id'] = 123;
$_SESSION['username'] = 'Alice';
$_SESSION['cart'] = ['item1', 'item2'];
echo "欢迎,{$_SESSION['username']}!";
核心函数速查
| 函数 | 用途 | 示例 |
session_start() | 启动/恢复会话,发送 Set-Cookie 头 | 每个页面最顶部调用一次 |
session_id() | 获取/设置当前会话 ID | session_id($customId) |
session_name() | 获取/设置会话 Cookie 名称(默认 PHPSESSID) | session_name('MYAPP') |
session_destroy() | 销毁服务端会话数据(文件/数据库/Redis) | 登出时调用 |
session_unset() | 清空 $_SESSION 变量(不删除服务端数据) | 重置当前会话 |
session_regenerate_id() | 生成新 Session ID,可选删除旧文件 | 登录后、权限变更后调用防固定攻击 |
session_encode() | 序列化当前 $_SESSION 为字符串 | 调试、备份 |
session_decode() | 解析编码字符串填充 $_SESSION | 测试、跨进程同步 |
php.ini 关键配置
; 存储驱动:files / memcached / redis / 自定义
session.save_handler = files
session.save_path = "/var/lib/php/sessions"
; Cookie 设置
session.name = PHPSESSID
session.cookie_lifetime = 0 ; 0=浏览器关闭失效,秒数=持久化
session.cookie_path = /
session.cookie_domain = ; 如 .example.com 共享子域
session.cookie_secure = On ; 仅 HTTPS 传输(生产必开)
session.cookie_httponly = On ; 禁止 JS 访问(防 XSS)
session.cookie_samesite = Lax ; CSRF 防护
; 安全
session.use_strict_mode = On ; 拒绝未初始化的 Session ID
session.sid_length = 32 ; ID 长度(建议 ≥ 32)
session.sid_bits_per_character = 5 ; 字符集熵
; 垃圾回收
session.gc_probability = 1
session.gc_divisor = 1000 ; 1/1000 概率触发 GC
session.gc_maxlifetime = 1440 ; 秒,数据最大生存时间
常见场景实战
1. 访问计数器
<?php
session_start();
$count = ($_SESSION['visit_count'] ?? 0) + 1;
$_SESSION['visit_count'] = $count;
echo "您是第 $count 次访问。";
2. 登录状态管理
<?php
// login.php
session_start();
// 验证用户名密码...
if ($valid) {
session_regenerate_id(true); // 防会话固定
$_SESSION['user_id'] = $user->id;
$_SESSION['roles'] = $user->roles;
header('Location: dashboard.php');
exit;
}
// dashboard.php
session_start();
if (empty($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
// 权限检查
if (!in_array('admin', $_SESSION['roles'] ?? [])) {
http_response_code(403);
exit('Forbidden');
}
3. 购物车(数组存储)
<?php
session_start();
$cart = $_SESSION['cart'] ?? [];
// 添加
$cart[] = ['product_id'=>101, 'qty'=>2, 'price'=>99.00];
$_SESSION['cart'] = $cart;
// 结算时遍历
$total = 0;
foreach ($_SESSION['cart'] as $item) {
$total += $item['qty'] * $item['price'];
}
4. 登出销毁
<?php
session_start();
$_SESSION = []; // 清空变量
if (ini_get('session.use_cookies')) {
$params = session_get_cookie_params();
setcookie(session_name(), '', time()-42000,
$params['path'], $params['domain'],
$params['secure'], $params['httponly']
);
}
session_destroy(); // 删除服务端存储
header('Location: login.php');
集群环境 Session 共享方案
| 方案 | 原理 | 优点 | 缺点 |
| 文件系统共享 (NFS/GlusterFS) | 多台服务器挂载同一目录 | 零代码改动 | 单点故障、I/O 瓶颈、锁竞争 |
| 数据库存储 | 自定义 SessionHandler 写入 MySQL/PostgreSQL | 持久化、可查询、ACID | 高并发下数据库压力大 |
| Memcached | session.save_handler=memcached | 高性能、原生支持、自动过期 | 无持久化、LRU 淘汰、1MB 限制 |
| Redis (推荐) | session.save_handler=redis (phpredis) | 持久化可选、集群、大 Value、原子操作 | 需额外扩展、配置稍复杂 |
| 客户端 Cookie (JWT/加密 Cookie) | 数据全存在客户端,签名防篡改 | 无服务端状态、水平扩展最简单 | 大小限 4KB、撤销难、敏感数据风险 |
安全加固清单
- HTTPS 全站 + Secure + HttpOnly + SameSite=Lax。
- session.use_strict_mode=On 防会话固定。
- 登录/权限变更后 session_regenerate_id(true)。
- 设置合理 gc_maxlifetime,配合 Redis TTL 双重保障。
- 敏感操作二次验证(修改密码、支付需重新输入密码/验证码)。
- 监控 Session 并发数、GC 频率、存储体积。
总结
PHP Session 通过 session_start() + $_SESSION 提供简洁的状态管理。生产环境务必配置安全 Cookie 属性、严格模式、集群共享存储(首选 Redis)、会话固定防护。理解「客户端只存 ID,服务端存数据」的本质,灵活运用 session_regenerate_id、自定义 SessionHandlerInterface,即可构建健壮可扩展的会话系统。