$_COOKIE 是只读超全局数组,不能直接赋值修改;必须用 setcookie() 在输出前设置,且删除需用过期时间+相同 path/domain 参数覆盖。

$_COOKIE 不能直接赋值写入,它只是只读的接收容器;真正设置 Cookie 必须用 setcookie(),且必须在任何输出之前调用。
为什么修改 $_COOKIE 不生效
常见错误是像这样写:$_COOKIE['theme'] = 'dark'; —— 这完全无效。因为 $_COOKIE 是 PHP 在请求开始时自动填充的只读数组,它反映的是浏览器本次发来的 Cookie 数据,不是服务端可写的存储区。
- 试图给
$_COOKIE赋值,既不会发送 HTTP Set-Cookie 头,也不会影响浏览器行为 - 该操作仅在当前脚本生命周期内修改了这个数组副本,下一次请求仍按原 Cookie 值重建
$_COOKIE - 真正写入浏览器的唯一方式是调用
setcookie()并确保它在header()发送前执行
setcookie() 的关键参数和易错点
setcookie() 看似简单,但漏掉一个参数就可能让 Cookie 不生效、不安全或作用域失控。
-
expire设为 0 或省略 → 变成会话 Cookie(关闭浏览器即失效),不是“永久” -
path默认是当前脚本所在路径(如/admin/login.php会默认设为/admin/),若想全站可用,必须显式传'/' -
domain若填'example.com',则www.example.com和api.example.com都能读取;填'.example.com'效果相同,但更明确 -
secure和httponly不设为true→ 敏感 Cookie 可能被 JS 读取或明文传输 - PHP 7.3+ 支持关联数组语法,推荐用:
setcookie('token', $val, ['expires' => time()+3600, 'path' => '/', 'domain' => 'example.com', 'secure' => true, 'httponly' => true, 'samesite' => 'Lax'])
读取 Cookie 时必须检查是否存在
$_COOKIE 数组里没有的键会触发 Notice: Undefined index,尤其在首次访问或用户清除了 Cookie 时。
立即学习“PHP免费学习笔记(深入)”;
- 别直接写
echo $_COOKIE['user_id']; - 应始终用
isset($_COOKIE['user_id'])或array_key_exists('user_id', $_COOKIE)判断 - 若需默认值,用空合并操作符:
$theme = $_COOKIE['theme'] ?? 'light'; - 注意:Cookie 值始终是字符串,即使你存的是数字
123,读出来也是'123',需要手动类型转换
删除 Cookie 的正确姿势
所谓“删除”,其实是用 setcookie() 发送一个已过期的同名 Cookie,让浏览器主动清除它。
- 必须保证
path和domain参数与当初设置时完全一致,否则浏览器认为是另一个 Cookie - 最稳妥写法:
setcookie('session_id', '', ['expires' => 1, 'path' => '/', 'domain' => 'example.com', 'secure' => true, 'httponly' => true]); - 不要依赖
unset($_COOKIE['xxx'])—— 它只删本地数组,对浏览器毫无影响 - 如果原 Cookie 是通过
setrawcookie()设置的,也得用setrawcookie()删除才保险
最容易被忽略的是 path 和 domain 的一致性 —— 同一个 Cookie,在 /admin/ 下设置,却在 / 下尝试删除,浏览器根本不会理你。



















