PHP: Cookie
HTTP 是无状态的——服务器不会记住你是谁。Cookie 解决了这个问题:服务器给你的浏览器一小块"便利贴",下次浏览器带着它回来,服务器就能说"哦,是你!"。
1. Cookie 是什么?
Cookie 是服务器让浏览器存储在用户电脑上的小段数据(≤4KB),每次请求时浏览器会自动带上。
TEXT
📖 仅展示
第一次访问:
浏览器 → 服务器:你好!
服务器 → 浏览器:给你个 Cookie:user=小明
下次访问:
浏览器 → 服务器:你好,这是我的 Cookie:user=小明
服务器:哦,小明,你的购物车还在!
PHP
<?php
// 创建 Cookie
setcookie("username", "小明", time() + 3600, "/");
// 读取 Cookie
echo $_COOKIE['username'] ?? '游客'; // 小明(刷新页面后依然有)
?>
2. setcookie() 参数详解
PHP
setcookie(
string $name, // Cookie 名字
string $value = "", // Cookie 值
int $expires = 0, // 过期时间(Unix时间戳,0=浏览器关闭时删除)
string $path = "", // 有效路径("/"=全站)
string $domain = "", // 有效域名
bool $secure = false, // 仅 HTTPS 发送
bool $httponly = false // JS 不可读
);
PHP
<?php
// 最简单的 Cookie(浏览器关闭后删除)
setcookie("visit_count", "1");
// 1小时后过期的 Cookie
setcookie("username", "小明", time() + 3600, "/");
// 7天后过期的 Cookie
setcookie("remember_token", "abc123", time() + 86400 * 7, "/");
// 安全 Cookie(仅 HTTPS,JS 不可读)
setcookie("session_id", "xyz789", [
'expires' => time() + 3600,
'path' => '/',
'secure' => true, // 仅 HTTPS
'httponly' => true, // 防 XSS 窃取
'samesite' => 'Lax' // 防止 CSRF
]);
?>
💡 提示: PHP 7.3+ 推荐用数组方式的
setcookie,参数名清晰不易弄混顺序。
3. 读取 Cookie:$_COOKIE
PHP
<?php
$username = $_COOKIE['username'] ?? '游客';
echo "欢迎,{$username}!";
// $_COOKIE 是一个超全局关联数组
print_r($_COOKIE);
// Array ( [username] => 小明 [visit_count] => 5 )
?>
▶ 示例:访问计数器
PHP
<?php
// 首次访问
if (!isset($_COOKIE['visit_count'])) {
setcookie('visit_count', 1, time() + 86400 * 30, "/");
echo "欢迎首次访问!";
} else {
$count = (int)$_COOKIE['visit_count'] + 1;
setcookie('visit_count', $count, time() + 86400 * 30, "/");
echo "您是第 {$count} 次访问!";
}
?>
4. 删除 Cookie
没有专门的"删除 Cookie"函数——把过期时间设为过去:
PHP
<?php
// 删除 Cookie
setcookie("username", "", time() - 3600, "/");
// 过期时间在过去 → 浏览器会删除它
// 也可以用 unset(只删除当前请求中的 $_COOKIE 值,不删除浏览器中的)
unset($_COOKIE['username']);
// 这只影响当前脚本,刷新后 Cookie 还在
?>
🔥 易错:
setcookie("name", "", time()-3600) 才能从浏览器中删除 Cookie。unset($_COOKIE['name']) 只删当前请求的变量。
5. Cookie 的安全属性
| 属性 | 作用 | 推荐 |
|---|---|---|
httponly |
JS 无法读取(防 XSS 窃取) | ✅ 永远开启 |
secure |
仅 HTTPS 传输 | ✅ 生产环境开启 |
samesite |
仅同站请求发送(防 CSRF) | Lax 或 Strict |
path |
限制在特定路径 | "/" 表示全站 |
PHP
<?php
// 安全的 Cookie 设置模板
setcookie("user_token", $token, [
'expires' => time() + 86400 * 30,
'path' => '/',
'secure' => isset($_SERVER['HTTPS']),
'httponly' => true,
'samesite' => 'Lax'
]);
?>
6. Cookie 的实际应用
▶ 示例:记住用户名
PHP
<?php
// remember.php
$savedName = $_COOKIE['saved_username'] ?? '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = trim($_POST['username'] ?? '');
$remember = isset($_POST['remember']);
if ($remember) {
// "记住我":存 30 天
setcookie('saved_username', $username, time() + 86400 * 30, '/');
} else {
// 不记住:删除 Cookie
setcookie('saved_username', '', time() - 3600, '/');
}
echo "<h3>欢迎回来,{$username}!</h3>";
}
?>
<form method="POST">
<input type="text" name="username"
value="<?= htmlspecialchars($savedName) ?>"
placeholder="输入用户名">
<label>
<input type="checkbox" name="remember"> 记住我
</label>
<button type="submit">登录</button>
</form>
▶ 示例:主题偏好
PHP
<?php
// theme.php
$theme = $_COOKIE['theme'] ?? 'light';
if (isset($_GET['theme'])) {
$theme = $_GET['theme'] === 'dark' ? 'dark' : 'light';
setcookie('theme', $theme, time() + 86400 * 365, '/');
}
?>
<!DOCTYPE html>
<html>
<head>
<style>
body.dark { background: #222; color: #eee; }
body.light { background: #fff; color: #333; }
</style>
</head>
<body class="<?= $theme ?>">
<h2>当前主题:<?= $theme === 'dark' ? '深色' : '浅色' ?></h2>
<a href="?theme=dark">深色模式</a> |
<a href="?theme=light">浅色模式</a>
</body>
</html>
7. Cookie 的局限性
| 限制 | 数据 |
|---|---|
| 单个 Cookie 大小 | ≤ 4096 字节(4KB) |
| 每个域名 Cookie 总数 | 约 20-50 个(浏览器不同) |
| 所有 Cookie 总大小 | 约 8KB |
| 安全性 | 明文存储,用户可查看和修改 |
| 传输 | 每次 HTTP 请求都会附带 |
💡 提示: Cookie 适合存少量、不敏感的数据(记住用户名、主题偏好)。存大量数据或敏感信息用 Session(下一课),存长期数据用数据库。
❓ 常见问题
Q Cookie 和 Session 有什么区别?
A Cookie 存浏览器,Session 存服务器。Cookie 大小有限、用户可篡改;Session 更安全但占用服务器资源。登录状态用 Session,"记住我"功能用 Cookie。
Q 用户能修改 Cookie 吗?
A 能!Cookie 存在用户的电脑上,用户完全可以修改。永远不要在不加密的情况下把敏感数据(如密码)存 Cookie 里。用
httponly 至少能防止 JS 脚本窃取。📖 小节
- Cookie 是浏览器端的键值对存储,每次请求自动发送
setcookie(name, value, expire, path)创建 Cookie- 过期时间设为过去 → 删除 Cookie
$_COOKIE是本请求携带的 Cookie(setcookie后需刷新才能读到)httponly(防 JS 读取)+secure(仅 HTTPS)+samesite(防 CSRF)- Cookie 限 4KB、可被用户修改、适合小量非敏感数据
📝 作业
- 实现"记住用户名"功能:登录表单中用户勾选"记住我"后,下次访问自动填充用户名。
- 写一个"主题切换器":用户在页面上点击切换浅色/深色主题,用 Cookie 记住偏好并保持到下次访问。
- 写一个"最近浏览"功能:用 Cookie 存储用户最近查看的 5 篇文章 ID(用逗号分隔字符串)。