PHP Sessions
PHP 会话
Section titled “PHP 会话”会话(Sessions)提供了一种跨多个页面请求存储用户特定信息(在变量中)的方式。这允许你在用户浏览网站时保持 状态(state)和用户数据。
与 cookie 不同,会话数据通常存储在 服务器(server)上,而不是用户的计算机上。通常只在 客户端(client-side)(通常在 cookie 中)存储一个唯一的 会话 ID(Session ID)。
什么是 PHP 会话?
Section titled “什么是 PHP 会话?”HTTP(Hypertext Transfer Protocol),作为网络的底层 协议,本质上是 无状态(stateless)的。这意味着浏览器向 Web 服务器发出的每个 请求(request)都是独立的;服务器不会自动记住与同一用户之前的交互。
想象一下访问一个在线商店。如果没有 会话,你将无法将商品添加到购物车,因为服务器会忘记你在上一页添加的内容。会话通过为用户的访问创建一个持久的“ 上下文(context)”来解决这个问题。
PHP 会话允许你将用户信息(如用户名、偏好设置、购物车商品)存储在与唯一 会话 ID 关联的服务器端变量中。这个 ID 在浏览器和服务器之间来回发送,允许 PHP 为每个用户请求检索正确的会话数据。
默认情况下,会话数据持续到用户关闭浏览器。对于超出浏览器 会话 的持久存储,你通常会使用 数据库(database)。
| 🔑 | 工作原理: 当 会话 启动时,PHP 会生成一个唯一的 会话 ID(Session ID)(例如 a1b2c3d4e5f6g7h8)。这个 ID 通常会发送到浏览器并存储在 cookie 中。在后续 请求(request)中,浏览器将 会话 ID 发送回服务器。PHP 使用这个 ID 来查找并加载存储在服务器上的相应会话数据(通常在临时文件/temporary files 中)。 |
|---|
启动 PHP 会话
Section titled “启动 PHP 会话”在你想访问 会话 数据的所有页面上,都必须显式地启动或恢复 会话。这是通过 session_start() 函数实现的。
关键: session_start() 必须在任何 输出(output)发送到浏览器之前调用(包括 HTML、空白或 echo 语句)。这是因为它可能需要发送 HTTP 头(HTTP headers)(例如设置 会话 cookie)。
会话 变量通过 $_SESSION 超全局数组(superglobal array)(一个 关联数组/associative array)来存储和访问。
让我们创建一个页面(page1.php)来启动 会话 并存储一些数据:
<?php// 1. 启动或恢复会话// 必须在任何输出之前调用session_start();
// 2. 设置会话变量$_SESSION['username'] = 'JohnDoe';$_SESSION['theme'] = 'dark';$_SESSION['cart_items'] = ['item1', 'item5'];
?><!DOCTYPE html><html><head> <title>Session Page 1</title></head><body>
<h1>会话已启动</h1><p>会话变量已设置。</p><p>用户名: <?php echo htmlspecialchars($_SESSION['username']); ?></p><p><a href="page2.php">前往 Page 2</a></p>
</body></html>| ❗ | 位置: 记住,session_start(); 必须放在脚本的最顶部,在 <!DOCTYPE html> 标签或任何其他 输出(output)之前。 |
|---|
访问会话数据
Section titled “访问会话数据”现在,让我们创建第二个页面(page2.php)来访问我们在 page1.php 中存储在 会话 中的数据。
同样,我们必须首先调用 session_start() 函数来恢复与用户的 会话 ID 相关联的现有 会话。
<?php// 1. 启动或恢复会话session_start();
// 在访问会话变量之前检查它们是否存在$username = isset($_SESSION['username']) ? htmlspecialchars($_SESSION['username']) : 'Guest';$theme = isset($_SESSION['theme']) ? htmlspecialchars($_SESSION['theme']) : 'light';
?><!DOCTYPE html><html><head> <title>Session Page 2</title> <style> body { background-color: <?php echo ($theme === 'dark' ? '#333' : '#fff'); ?>; color: <?php echo ($theme === 'dark' ? '#fff' : '#000'); ?>; } </style></head><body>
<h1>欢迎回来, <?php echo $username; ?>!</h1><p>您选择的主题是: <?php echo $theme; ?></p>
<h2>所有会话数据:</h2><pre><?php// 显示所有会话数据用于调试(在生产环境中谨慎使用)print_r($_SESSION);?></pre>
<p><a href="page1.php">返回 Page 1</a></p><p><a href="logout.php">注销 (销毁会话)</a></p>
</body></html>在使用 isset() 检查 $_SESSION 变量是否存在之后再访问它们是一种良好的实践,可以避免变量尚未设置时产生的警告。
print_r($_SESSION); 在开发过程中非常有用,可以查看当前存储在 会话 中的所有变量。
修改会话变量
Section titled “修改会话变量”要更改 会话 变量的值,只需覆盖 $_SESSION 数组中的元素。确保已经调用了 session_start() 函数。
<?phpsession_start();
// 修改主题变量if (isset($_SESSION['theme'])) { $_SESSION['theme'] = 'light'; echo "Theme changed to light.";} else { echo "Theme variable not set initially.";}
// 向购物车数组添加一个项目if (!isset($_SESSION['cart_items']) || !is_array($_SESSION['cart_items'])) { $_SESSION['cart_items'] = []; // 如果不存在或不是数组,则初始化}$_SESSION['cart_items'][] = 'item12'; // 添加新项目
echo "<br>更新后的会话数据:";print_r($_SESSION);?>当用户注销或你想完全清除其 会话 数据时,你需要销毁 会话。
标准过程包括三个步骤:
- 使用
session_start()函数启动或恢复 会话。 - 使用
session_unset()或将一个空数组赋值给$_SESSION = array();来 销毁(Unset)所有 会话 变量。 - 使用
session_destroy()函数 销毁 会话 本身。这将从服务器存储中移除 会话 数据。
此外,你也可以选择从用户浏览器中移除 会话 cookie,以确保完全 清理(cleanup)。
示例(logout.php):
<?php// 1. 启动会话session_start();
// 2. 销毁所有会话变量$_SESSION = array(); // 或 session_unset();
// 3. 销毁会话 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"] );}
// 4. 销毁会话session_destroy();
?><!DOCTYPE html><html><body>
<h1>已注销</h1><p>您的会话已销毁。</p><p><a href="page1.php">重新开始</a></p>
</body></html>会话安全:在 php.ini 文件中或通过 ini_set() 函数安全配置 会话 是非常重要的。关键设置包括 session.cookie_httponly(阻止客户端脚本访问 cookie)、session.use_strict_mode(防止 会话固定/session fixation)和 session.cookie_secure(仅通过 HTTPS 发送 cookie)。在登录时重新生成 会话 ID(session_regenerate_id(true))对于防止 会话劫持(session hijacking)也至关重要。