setcookie(
string $name,
string $value = "",
int $expires_or_options = 0,
string $path = "",
string $domain = "",
bool $secure = false,
bool $httponly = true
): bool
// PHP 7.3+ 支持选项数组
setcookie($name, $value, [
'expires' => time() + 3600,
'path' => '/',
'domain' => '.example.com',
'secure' => true,
'httponly' => true,
'samesite' => 'Lax',
]);
| 参数 | 说明 | 推荐值 |
|---|---|---|
name | Cookie 名称(键) | 语义化,如 user_id, csrf_token |
value | 值,字符串。复杂数据需序列化 | json_encode() / serialize() |
expires | Unix 时间戳。0/省略 = 会话级(关闭浏览器失效) | time() + 86400 (1天) 或 time() + 31536000 (1年) |
path | 生效路径 | / (全站) |
domain | 生效域名。.example.com 含子域名 | 主域名带点前缀 |
secure | 仅 HTTPS 传输 | true (生产环境必须) |
httponly | 禁止 JS 访问 (防 XSS) | true |
samesite | 跨站发送策略:Lax/Strict/None | Lax (平衡安全与体验) |
<?php
// 简单值,1小时过期,全站,安全属性全开
setcookie('lang', 'zh-CN', time() + 3600, '/', '', true, true);
// 选项数组写法(PHP 7.3+ 推荐,可读性更强)
setcookie('theme', 'dark', [
'expires' => time() + 86400 * 30,
'path' => '/',
'secure' => true,
'httponly' => true,
'samesite' => 'Lax',
]);
<?php
// 写入
$cart = [
['id' => 1, 'qty' => 2],
['id' => 5, 'qty' => 1],
];
setcookie('cart', json_encode($cart), time() + 3600, '/', '', true, true);
// 读取
$cart = json_decode($_COOKIE['cart'] ?? '[]', true);
// 安全:验证结构
if (!is_array($cart)) $cart = [];
注意: Cookie 总大限 4KB,数组数据量大时改用服务端 Session + Cookie 仅存 ID。
<?php
// 必须匹配设置时的 path、domain、secure
setcookie('cart', '', time() - 3600, '/', '', true, true);
// 或选项数组
setcookie('cart', '', ['expires' => time() - 3600, 'path' => '/', 'secure' => true, 'httponly' => true]);
| 现象 | 原因 | 解决 |
|---|---|---|
| Cookie 不生效 | setcookie 在输出后调用 | 移至脚本最顶端,或开启 output_buffering |
| 子域名不共享 | domain 未设为 .example.com | 显式设置 domain |
| HTTPS 下丢失 | secure=true 但测试环境用 HTTP | 本地开发用 lvh.me + mkcert 配置 HTTPS,或测试时关闭 secure |
| JS 读不到 | httponly=true | 前端确需读取时设为 false(慎用) |
| 值被截断/损坏 | 含分号、逗号、空格等特殊字符 | 存储前 urlencode() / base64_encode() |
hash_hmac('sha256', $value, $secret) 验证完整性。setcookie() 参数虽多,但核心就三点:作用域,生命周期,安全属性。生产环境务必「全站路径、带点域名、Secure、HttpOnly、SameSite=Lax」,复杂数据用 JSON 序列化,大数据改用服务端存储。避开「输出前调用」「域名不匹配」两大坑,Cookie 管理即可得心应手。