PHP $_COOKIE
Cookie(小甜饼)是服务器发送到 Web 浏览器的一小段数据。浏览器会将其保存在本地,并在随后向同一个域名发起的每一次请求中,自动将这段数据携带并发送回服务器。在 PHP 中,$_COOKIE 超全局数组为我们提供了读取这些值的接口,允许你在多个页面的加载过程中持久保存用户信息——例如语言偏好设置、购物车 ID 或“记住我”的登录令牌。
1. 使用 setcookie() 创建 Cookie
在你能从 $_SESSION 或 $_COOKIE 中读取 Cookie 之前,必须先创建它。你可以使用 setcookie() 函数来指示浏览器存储数据。由于 Cookie 是作为 HTTP 头部(Header)的一部分发送的,因此 setcookie() 函数必须在向浏览器发送任何输出之前调用(包括任何 HTML 标签,甚至是一个空格)。
<?php
// 语法:setcookie(名称, 值, 过期时间或选项数组, 路径, 域名, 是否仅限HTTPS, 是否仅限HTTP访问)
// 创建一个简单的持久化 Cookie,有效期为 30 天
$cookieName = "user_theme";
$cookieValue = "dark-mode"; // 暗黑模式
$expiration = time() + (86400 * 30); // 86400 秒 = 1 天
setcookie($cookieName, $cookieValue, $expiration, "/");
?>2. 从 $_COOKIE 中读取数据
一旦浏览器存储了该 Cookie,它就会自动将其包含在未来对你域名发起的所有请求的 HTTP 头部中。PHP 会自动提取这些值并填充到 $_COOKIE 超全局数组里。访问它们就像访问任何其他关联数组一样简单。
<?php
// 使用 isset() 检查 Cookie 是否存在
if (isset($_COOKIE['user_theme'])) {
$theme = $_COOKIE['user_theme'];
// 输出时务必使用 htmlspecialchars 防御 XSS 攻击
echo "当前主题偏好: " . htmlspecialchars($theme);
} else {
echo "未设置主题偏好。正在使用默认主题。";
}
?>3. Cookie 安全注意事项
Cookie 是完全存储在客户端(浏览器)的,这意味着它们天生就是不安全的。绝对不要将敏感数据(如明文密码、信用卡号或明文的用户 ID)直接存储在 Cookie 中。在设置 Cookie 时,强烈建议始终使用 httponly 和 secure 标志,以防范常见的 Web 漏洞。
- httponly (仅限 HTTP): 如果设置为
true,该 Cookie 将无法通过 JavaScript 访问。这能有效防止跨站脚本(XSS)攻击窃取会话 Cookie。 - secure (安全连接): 如果设置为
true,该 Cookie 将只通过 HTTPS 加密连接发送,确保数据在传输过程中的加密安全。
<?php
// 使用 PHP 7.3+ 支持的选项数组语法设置高安全级别的 Cookie
setcookie("session_token", "abc123xyz", [
'expires' => time() + 3600, // 1 小时后过期
'path' => '/', // 全站可用
'domain' => 'example.com', // 你的域名
'secure' => true, // 仅通过 HTTPS 发送
'httponly' => true, // 禁止 JavaScript 访问
'samesite' => 'Strict' // 缓解 CSRF(跨站请求伪造)攻击
]);
?>4. Cookie 的生命周期
下面展示了服务器如何与客户端通信,从而建立和持久化基于 Cookie 的状态。
- HTTP 请求: 用户(浏览器)向 PHP 服务器发起请求。
- HTTP 响应(携带 Set-Cookie): 服务器处理逻辑后,在响应头中包含
Set-Cookie指令返回给浏览器。 - 本地存储: 浏览器接收到指令,将 Cookie 存储在用户的本地硬盘/内存中。
- 后续 HTTP 请求: 浏览器再次请求该网站时,会自动在请求头中包含
Cookie数据。 - PHP 读取: 服务器端的 PHP 脚本通过
$_COOKIE['key']成功读取该数据。
5. 删除 Cookie
要删除一个 Cookie,你需要调用 setcookie() 函数,使用与现有 Cookie 相同的名称,但将其过期时间设置为过去的一个时间点。这会强制浏览器立即丢弃该 Cookie。
<?php
// 通过将时间设置为 1 小时前,使 Cookie 立即过期并删除
setcookie("user_theme", "", time() - 3600, "/");
?>