PHP Session 解决了一个 Web 开发里很根本的问题:同一个用户在不同页面之间跳转时,如何让数据跟着走。Cookie 虽然也能存数据,但存在客户端,容量小且容易被篡改。Session 则把数据放在服务端,客户端只保留一个唯一标识(Session ID),安全性、容量都上了一个台阶。
购物车、用户登录态、多步骤表单这些场景,都依赖 Session 机制。它的生命周期从用户打开网站开始,到关闭浏览器或主动销毁时结束,属于临时性的数据存储方案。
PHP Session 的工作原理
整个流程可以拆成几步来理解。用户首次访问网站时,PHP 调用 session_start(),服务端生成一个全局唯一的 Session ID,格式类似一串随机字符串。这个 ID 通过名为 PHPSESSID 的 Cookie 写入用户浏览器。与此同时,服务端创建一个对应的存储文件(默认在 session.save_path 配置的目录下),后续所有 $_SESSION 数组里存的数据都序列化后写入这个文件。
当用户跳转到下一个页面时,浏览器自动携带 PHPSESSID Cookie 回来,PHP 再次调用 session_start() 时读到这个 ID,找到对应的存储文件,把数据反序列化回 $_SESSION 数组,页面就能拿到之前存的信息了。
整个交互过程建立在客户端 Cookie 与服务端存储的配合上。Cookie 只存 ID,数据全在服务端,这就是 Session 比纯 Cookie 方案更安全的根本原因。
session_start():一切会话操作的前提
session_start() 必须在任何页面输出之前调用,包括空格、BOM 头、HTML 标签。这个要求跟 setcookie() 的原因一样——它需要发送包含 Session ID 的 Cookie 头。
<?php
session_start(); // 放到文件最顶部
?>
<!DOCTYPE html>
<html>
...
调用后如果当前请求已经携带了有效的 Session ID,就恢复已有的会话;没有的话就创建新会话,分配新 ID。函数返回布尔值,不过基本不需要判断它的返回值,因为它失败时会直接报错。
记录会话启动时间的例子:
<?php
session_start();
$_SESSION['session_start'] = time();
echo "本次会话开始于:" . date('Y-m-d H:i:s', $_SESSION['session_start']);
?>
这里 time() 返回当前 Unix 时间戳,存入 $_SESSION 数组后,页面刷新也不会变,因为 Session 数据持久存在于服务端。
再做一个简单的页面访问计数器:
<?php
session_start();
if (!isset($_SESSION['page_views'])) {
$_SESSION['page_views'] = 1;
} else {
$_SESSION['page_views']++;
}
echo "你在本次会话中的页面访问次数:{$_SESSION['page_views']}";
?>
刷新一次加一,关闭浏览器后重开又归零重新计数。这个特性很适合做短期的用户行为统计。
$_SESSION 超全局数组:存什么、怎么取
$_SESSION 是一个关联数组,语法和普通数组一样。存字符串、数字、布尔值、甚至数组和对象都行。
存储数据:
<?php
session_start();
$_SESSION['student_name'] = '张三';
$_SESSION['course_list'] = ['PHP基础', 'MySQL入门', 'JavaScript教程'];
$_SESSION['logged_in'] = true;
?>
在其他页面读取:
<?php
session_start();
echo "欢迎," . htmlspecialchars($_SESSION['student_name']);
echo "你已选择的课程:" . implode('、', $_SESSION['course_list']);
?>
跨页面的典型使用场景:登录成功后把用户信息存 Session,后续每个受保护页面先判 $_SESSION['logged_in'] 是否为 true,为 false 就跳转回登录页。整个鉴权体系基于这个简单逻辑构建。
两个页面串联演示,先看 set_session.php:
<?php
session_start();
$_SESSION['user'] = '李四';
$_SESSION['role'] = 'admin';
echo "Session 数据已写入。<br>";
echo '<a href="get_session.php">查看 Session 数据</a>';
?>
再看 get_session.php:
<?php
session_start();
if (isset($_SESSION['user'])) {
echo "当前用户:" . htmlspecialchars($_SESSION['user']) . "<br>";
echo "角色:" . htmlspecialchars($_SESSION['role']);
} else {
echo "未检测到登录信息,请先设置 Session。";
}
?>
点击链接跳转后能看到之前设置的用户名和角色。这就是 Session 跨页面传递数据的核心用法。
登录态实战
模拟一个简化版登录流程。login.php 处理登录并写入 Session:
<?php
session_start();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// 实际项目这里要查数据库校验密码
$_SESSION['logged_in'] = true;
$_SESSION['username'] = $_POST['username'] ?? '匿名用户';
echo "登录成功," . htmlspecialchars($_SESSION['username']);
}
?>
<form method="POST">
<input type="text" name="username" placeholder="用户名">
<button type="submit">登录</button>
</form>
dashboard.php 做受保护页面:
<?php
session_start();
if (empty($_SESSION['logged_in'])) {
die('请先登录再访问此页面。');
}
echo "欢迎回来," . htmlspecialchars($_SESSION['username']) . ",这是你的控制面板。";
?>
没登录直接访问 dashboard.php 会被拦截,登录后就能正常看到内容。项目开发里这个判断逻辑通常会抽成一个公共函数,放在每个需要鉴权的页面顶部引用,避免到处写重复代码。
销毁 Session:退出登录的步骤
session_destroy() 删除服务端的 Session 数据文件,但 $_SESSION 数组在当前请求里仍然保留了值。通常退出登录时要一并清空数组,并把客户端的 PHPSESSID Cookie 也删干净。
三段式退出操作:
<?php
session_start();
// 第一步:清空 $_SESSION 数组
$_SESSION = [];
// 第二步:删除客户端的 Session Cookie
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 数据
session_destroy();
echo "已退出登录。";
?>
很多人只用 session_destroy() 就完事,结果发现退出后刷新页面,旧的 Session 值偶尔还在。原因就在于 Cookie 和数组没清。这个三步走的退出流程能确保退出成功。我在接手一个旧项目时,用户反馈退出后还能短暂看到上一个人的购物车数据,排查后发现就是只调了 session_destroy() 没清 Cookie,导致下一次请求又携带旧 Session ID,而服务端那个 ID 对应的文件还在。
本节课程知识要点
Session 数据存放在服务端,客户端只通过 Cookie 传递 Session ID,这使得 Session 比纯 Cookie 存储更安全、容量更大。session_start() 是所有 Session 操作的先决条件,必须在页面输出前调用,每个用到 Session 的页面都要写。$_SESSION 是操作 Session 数据的接口,写法跟普通关联数组一样,页面间共享、生命周期内持久。退出登录要做三件事——清空数组、删除 Cookie、销毁服务端文件——丢一步都可能导致退出不彻底。Session 默认存储为服务端临时文件,在并发大的场景下可以改用 Redis 或 Memcached 做 Session 存储后端,提升读写性能。另外 session.gc_maxlifetime 配置项决定 Session 文件的回收周期,跟用户感知的“登录保持时长”直接相关,值得关注。