setcookie() 函数用于设置一个 Cookie。
Cookie 是服务器发送到用户浏览器并保存在本地的一小块数据。浏览器会存储这些数据,并在后续请求中将其发送回服务器。Cookie 通常用于:
setrawcookie() 函数。
setcookie ( string $name [, string $value = "" [, int $expires = 0 [, string $path = "" [, string $domain = "" [, bool $secure = false [, bool $httponly = false ]]]]]] ) : bool
从 PHP 7.3.0 开始,支持数组参数格式:
setcookie ( string $name , string $value = "" , array $options = [] ) : bool
| 参数 | 类型 | 描述 |
|---|---|---|
$name |
string | 必需的。Cookie 的名称。 |
$value |
string |
可选的。Cookie 的值。如果为空字符串,则创建一个空值 Cookie。
注意:不要在 Cookie 值中存储敏感信息。Cookie 存储在用户浏览器中,可能被用户查看或修改。
|
$expires |
int |
可选的。Cookie 的过期时间,以 Unix 时间戳表示。
|
$path |
string |
可选的。Cookie 有效的服务器路径。默认为当前目录。
|
$domain |
string |
可选的。Cookie 有效的域名。默认为当前域名。
|
$secure |
bool |
可选的。如果设置为 true,Cookie 仅通过 HTTPS 连接传输。
安全最佳实践:在生产环境中,应始终通过 HTTPS 传输 Cookie。
|
$httponly |
bool |
可选的。如果设置为 true,Cookie 只能通过 HTTP 协议访问,JavaScript 无法访问。
安全最佳实践:设置为
true 可以防止 XSS 攻击窃取 Cookie。
|
$options (PHP 7.3+) |
array |
可选的。包含上述所有参数(除 $name 和 $value)的关联数组,支持更多选项:
|
| 返回值 | 描述 |
|---|---|
true |
如果成功设置 Cookie 头信息。这并不意味着用户浏览器接受了 Cookie。 |
false |
如果设置失败。通常是因为:
|
设置一个名为 "user" 的 Cookie,值为 "John Doe",过期时间为 1 小时。
<?php
// 设置一个简单的 Cookie
$cookie_name = "user";
$cookie_value = "John Doe";
$expiry_time = time() + (60 * 60); // 1小时后过期
if (setcookie($cookie_name, $cookie_value, $expiry_time)) {
echo "Cookie '$cookie_name' 已设置成功。\n";
} else {
echo "设置 Cookie 失败。\n";
}
// 注意:新设置的 Cookie 在下一次页面加载时才能通过 $_COOKIE 访问
if (isset($_COOKIE[$cookie_name])) {
echo "Cookie 值: " . $_COOKIE[$cookie_name];
} else {
echo "Cookie 尚未在当前请求中可用。请刷新页面。";
}
?>
设置一个包含所有参数的完整 Cookie。
<?php
// 设置一个完整的 Cookie
$cookie_name = "preferences";
$cookie_value = json_encode([
'theme' => 'dark',
'language' => 'zh-CN',
'notifications' => true
]);
$expires = time() + (86400 * 30); // 30天后过期
$path = "/"; // 整个站点有效
$domain = ""; // 当前域名(可设为 ".example.com" 使所有子域名有效)
$secure = true; // 仅通过 HTTPS 传输
$httponly = true; // 防止 JavaScript 访问
if (setcookie($cookie_name, $cookie_value, $expires, $path, $domain, $secure, $httponly)) {
echo "偏好设置 Cookie 已设置。\n";
}
// 解码并显示 Cookie 值
if (isset($_COOKIE[$cookie_name])) {
$preferences = json_decode($_COOKIE[$cookie_name], true);
echo "当前主题: " . ($preferences['theme'] ?? '未设置') . "\n";
}
?>
使用新的数组参数格式设置 Cookie(推荐用于 PHP 7.3+)。
<?php
// PHP 7.3+ 新语法
if (version_compare(PHP_VERSION, '7.3.0', '>=')) {
// 使用数组参数格式
setcookie('session_id', 'abc123def456', [
'expires' => time() + (86400 * 7), // 7天后过期
'path' => '/',
'domain' => 'example.com',
'secure' => true,
'httponly' => true,
'samesite' => 'Strict' // SameSite 属性(PHP 7.3+)
]);
echo "使用新语法设置 Cookie 成功。\n";
} else {
// 传统语法
setcookie('session_id', 'abc123def456', time() + (86400 * 7), '/', 'example.com', true, true);
echo "使用传统语法设置 Cookie 成功。\n";
}
// SameSite 属性的解释
echo "SameSite 属性说明:\n";
echo "- Strict: 完全禁止第三方 Cookie\n";
echo "- Lax: 允许部分安全的第三方 Cookie(默认)\n";
echo "- None: 允许所有第三方 Cookie(必须同时设置 Secure)\n";
?>
通过设置过期时间为过去的时间来删除 Cookie。
<?php
// 删除名为 "user" 的 Cookie
$cookie_name = "user";
// 方法1:设置过期时间为过去的时间
if (setcookie($cookie_name, "", time() - 3600)) {
echo "Cookie '$cookie_name' 已删除。\n";
}
// 方法2:设置所有参数与创建时相同,但过期时间为过去
if (setcookie($cookie_name, "", time() - 3600, "/", "example.com", true, true)) {
echo "Cookie '$cookie_name' 已完全删除。\n";
}
// 方法3:使用 unset() 从 $_COOKIE 数组中移除(仅影响当前脚本)
unset($_COOKIE[$cookie_name]);
echo "从当前请求中移除了 Cookie '$cookie_name'。\n";
// 验证 Cookie 是否已删除
if (!isset($_COOKIE[$cookie_name])) {
echo "Cookie '$cookie_name' 不存在。\n";
}
?>
使用 Cookie 实现简单的登录状态管理。
<?php
// 登录处理
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['login'])) {
$username = $_POST['username'] ?? '';
$password = $_POST['password'] ?? '';
// 简单的认证检查(实际应用中应使用更安全的方法)
if ($username === 'admin' && $password === 'password123') {
// 创建会话标识符
$session_id = bin2hex(random_bytes(16));
// 设置 Cookie
setcookie('session_id', $session_id, [
'expires' => time() + (86400 * 7), // 7天有效
'path' => '/',
'secure' => true,
'httponly' => true,
'samesite' => 'Strict'
]);
// 在服务器端存储会话数据(实际应用中应使用数据库或会话存储)
// 这里使用文件存储作为示例
$session_data = [
'user_id' => 1,
'username' => $username,
'login_time' => time(),
'ip_address' => $_SERVER['REMOTE_ADDR']
];
file_put_contents("sessions/$session_id.json", json_encode($session_data));
echo "登录成功!已设置会话 Cookie。\n";
header("Location: /dashboard.php");
exit;
} else {
echo "用户名或密码错误。\n";
}
}
// 检查登录状态
function is_logged_in() {
if (!isset($_COOKIE['session_id'])) {
return false;
}
$session_id = $_COOKIE['session_id'];
$session_file = "sessions/$session_id.json";
if (!file_exists($session_file)) {
return false;
}
$session_data = json_decode(file_get_contents($session_file), true);
// 检查会话是否过期(24小时)
if (time() - $session_data['login_time'] > 86400) {
unlink($session_file); // 删除过期会话
return false;
}
return $session_data;
}
// 登出处理
if (isset($_GET['logout'])) {
if (isset($_COOKIE['session_id'])) {
$session_id = $_COOKIE['session_id'];
$session_file = "sessions/$session_id.json";
if (file_exists($session_file)) {
unlink($session_file);
}
// 删除 Cookie
setcookie('session_id', '', time() - 3600, '/', '', true, true);
}
echo "已登出。\n";
header("Location: /");
exit;
}
// 显示登录状态
$user_data = is_logged_in();
if ($user_data) {
echo "欢迎回来," . htmlspecialchars($user_data['username']) . "!\n";
} else {
echo "您尚未登录。\n";
}
?>
setcookie() 必须在任何输出之前调用,否则会导致 "headers already sent" 错误。可以使用 headers_sent() 函数检查。$secure 参数为 true)。$httponly 为 true 以防止 XSS 攻击。samesite 选项控制第三方 Cookie(推荐使用 "Strict" 或 "Lax")。$_COOKIE 数组中不可用,需要刷新页面或在下一次请求中才能访问。setcookie() 会自动对值进行 URL 编码。如果不需要编码,使用 setrawcookie()。| 实践 | 描述 |
|---|---|
| 使用 HTTPS | 始终设置 $secure = true,确保 Cookie 仅通过加密连接传输。 |
| HttpOnly 标志 | 设置 $httponly = true,防止 JavaScript 访问 Cookie,减少 XSS 攻击风险。 |
| SameSite 属性 | 使用 samesite = "Strict" 或 "Lax" 防止 CSRF 攻击。 |
| 合理的过期时间 | 根据需求设置适当的过期时间,避免过长的会话持续时间。 |
| 服务器端验证 | 不要信任 Cookie 中的数据,始终在服务器端进行验证。 |
| 加密敏感数据 | 如果需要存储敏感信息,应先加密再存入 Cookie。 |
| 限制路径和域 | 使用最严格的路径和域名限制,减少 Cookie 暴露范围。 |