PHP 入门教程
PHP Cookie 与 Session
本教程共 65 篇 · 第 27 篇 · 更新于 2026-07-24 · 约 5 分钟阅读
PHPPHP8CookieSession状态保持安全
27. PHP Cookie 与 Session
本节目标:理解 Cookie 和 Session 的工作原理,学会用 PHP 实现用户状态保持,了解常见的安全问题。
HTTP 是无状态协议,服务器默认记不住你是谁。Cookie 和 Session 就是解决这个问题的两大手段。
27.1 Cookie 基础
Cookie 是服务器发送到浏览器的一小段文本。浏览器保存后,每次访问同一站点都会带上它。
设置 Cookie
setcookie() 函数必须在任何输出之前调用:
<?php
// 设置一个 1 小时后过期的 Cookie
setcookie("username", "张三", time() + 3600);
// 更多参数:路径、域名、安全传输、HttpOnly
setcookie("token", "abc123", [
"expires" => time() + 86400,
"path" => "/",
"secure" => true, // 仅 HTTPS 传输
"httponly" => true, // 禁止 JS 读取
"samesite" => "Lax", // PHP 7.3+ 支持,防 CSRF
]);
echo "Cookie 已设置";
NotePHP 7.3 起推荐用关联数组形式传参,
samesite可以有效降低 CSRF 风险。
读取 Cookie
<?php
if (isset($_COOKIE["username"])) {
echo "欢迎回来," . htmlspecialchars($_COOKIE["username"]);
} else {
echo "你好,访客!";
}
// 查看所有 Cookie
print_r($_COOKIE);
删除 Cookie
把过期时间设为过去即可:
<?php
// 删除单个 Cookie
setcookie("username", "", time() - 3600);
// 删除时路径和域名要与设置时一致
setcookie("token", "", ["expires" => time() - 3600, "path" => "/"]);
27.2 Session 基础
Session 把数据存在服务器端,比 Cookie 更安全,适合保存敏感信息。
启动 Session
<?php
// 必须在脚本最开头,任何输出之前
session_start();
// 现在可以读写 $_SESSION 了
$_SESSION["user_id"] = 42;
$_SESSION["nickname"] = "小明";
echo "Session 已写入";
TipPHP 8.0 起
session_start()支持传入选项数组,如session_start(["cookie_lifetime" => 3600])。
读取与修改 Session
<?php
session_start();
// 读取
$userId = $_SESSION["user_id"] ?? null;
// 修改
$_SESSION["views"] = ($_SESSION["views"] ?? 0) + 1;
echo "这是你的第 {$_SESSION['views']} 次访问";
销毁 Session
<?php
session_start();
// 清空所有 Session 数据
$_SESSION = [];
// 删除 Cookie 中的 Session ID
if (isset($_COOKIE[session_name()])) {
setcookie(session_name(), "", [
"expires" => time() - 3600,
"path" => "/",
]);
}
// 彻底销毁服务器端 Session 文件
session_destroy();
27.3 Cookie 与 Session 的对比
| 特性 | Cookie | Session |
|---|---|---|
| 存储位置 | 浏览器端 | 服务器端 |
| 安全性 | 较低,可被查看/篡改 | 较高,用户看不到 |
| 容量限制 | 约 4KB | 受服务器内存/磁盘限制 |
| 性能 | 不占用服务器资源 | 需读写服务器文件/数据库 |
| 依赖关系 | 独立工作 | 通常通过 Cookie 传递 Session ID |
27.4 Session 的工作原理
- 第一次访问时,PHP 生成唯一的 Session ID(如
a1b2c3d4) - 通过
Set-Cookie: PHPSESSID=a1b2c3d4发给浏览器 - 浏览器后续请求自动带上这个 Cookie
- PHP 根据 ID 找到服务器上对应的 Session 文件,恢复
$_SESSION
<?php
session_start();
echo "当前 Session ID:" . session_id();
echo "<br>Session 保存路径:" . session_save_path();
27.5 Session 安全配置
重生成 Session ID
登录成功后应该更换 Session ID,防止固定会话攻击:
<?php
session_start();
// 验证用户名密码通过后...
$_SESSION["user_id"] = $userId;
$_SESSION["login_time"] = time();
// 重新生成 ID,并保留数据
session_regenerate_id(true);
Note
session_regenerate_id(true)的true参数会删除旧 Session 文件,防止被复用。
设置 Session 有效期
<?php
// 30 分钟无操作则过期
$timeout = 1800;
session_start();
if (isset($_SESSION["last_activity"]) && (time() - $_SESSION["last_activity"] > $timeout)) {
session_unset();
session_destroy();
}
$_SESSION["last_activity"] = time();
27.6 常见问题
- 页面提示 headers already sent:
session_start()或setcookie()前面不能有输出,包括 BOM 头和空格 - Session 数据丢失:检查
session.save_path目录是否有写入权限 - 跨子域共享 Session:设置
session_set_cookie_params(["domain" => ".example.com"])
来源:参考了 runoob「PHP Cookie」「PHP Session」、w3cschool「PHP Cookies」「PHP Sessions」等,改写后所得。