首页 / PHP 入门教程 / PHP Cookie 与 Session

PHP 入门教程

PHP Cookie 与 Session

本教程共 65 篇 · 第 27 篇 · 更新于 2026-07-24 · 约 5 分钟阅读

PHPPHP8CookieSession状态保持安全

27. PHP Cookie 与 Session

本节目标:理解 Cookie 和 Session 的工作原理,学会用 PHP 实现用户状态保持,了解常见的安全问题。

HTTP 是无状态协议,服务器默认记不住你是谁。Cookie 和 Session 就是解决这个问题的两大手段。

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 已设置";
Note

PHP 7.3 起推荐用关联数组形式传参,samesite 可以有效降低 CSRF 风险。

<?php
if (isset($_COOKIE["username"])) {
    echo "欢迎回来," . htmlspecialchars($_COOKIE["username"]);
} else {
    echo "你好,访客!";
}

// 查看所有 Cookie
print_r($_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 已写入";
Tip

PHP 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();
特性CookieSession
存储位置浏览器端服务器端
安全性较低,可被查看/篡改较高,用户看不到
容量限制约 4KB受服务器内存/磁盘限制
性能不占用服务器资源需读写服务器文件/数据库
依赖关系独立工作通常通过 Cookie 传递 Session ID

27.4 Session 的工作原理

  1. 第一次访问时,PHP 生成唯一的 Session ID(如 a1b2c3d4
  2. 通过 Set-Cookie: PHPSESSID=a1b2c3d4 发给浏览器
  3. 浏览器后续请求自动带上这个 Cookie
  4. 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 sentsession_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」等,改写后所得。