setcookie()必须在任何输出前调用,因依赖http头;$_cookie只读,修改需用setcookie();删cookie须路径/域名匹配并设过期时间;secure/httponly/samesite为安全刚需。

setcookie() 必须在任何输出之前调用
PHP 的 setcookie() 是个“头部操作”,它靠发送 HTTP Set-Cookie 响应头生效。一旦有哪怕一个空格、<?php echo '' ?> 的换行、或者 UTF-8 BOM,都会导致“headers already sent”错误。
- 常见错误现象:
Warning: Cannot modify header information - headers already sent by... - 检查点:确认文件开头没 BOM(用编辑器转成 UTF-8 without BOM),
echo、print、HTML 标签、甚至?><?php之间的空白都不能出现在setcookie()前 - 安全做法:把所有
setcookie()放在脚本最顶部,或统一收口到初始化逻辑里,避免分散在模板中 - 调试技巧:用
headers_sent($file, $line)查具体哪行先输出了
$_COOKIE 是只读数组,不能直接赋值修改
$_COOKIE 是 PHP 自动填充的超全局变量,它只是当前请求收到的 Cookie 快照,写入它不会触发 HTTP 头发送,也不会持久化。
- 常见错误现象:写了
$_COOKIE['user_id'] = 123;,刷新后还是旧值,甚至报Undefined index - 正确做法:要改 Cookie,必须调用
setcookie();要读值,直接取$_COOKIE['key']即可 - 注意:如果 Cookie 带了
HttpOnly(推荐),JS 无法读写,但 PHP 仍可通过$_COOKIE读取 - 兼容性提醒:PHP 8.0+ 默认禁用
register_globals,别指望靠变量名自动映射
删除 Cookie 要三要素匹配:名称 + 路径 + 域名
删 Cookie 不是“清空值”,而是发一个过期时间远在过去的同名 Cookie,让浏览器主动丢弃。路径和域名不一致,就等于删了个不存在的 Cookie。
- 常见错误现象:调了
setcookie('theme', '', time()-3600)却删不掉,因为原 Cookie 是用path='/admin/'设置的 - 实操建议:删时显式传参,和当初设时保持一致:
setcookie('theme', '', time()-3600, '/admin/', '', false, true) - 路径差异影响大:根路径
/设的 Cookie,子路径如/user/能读到;但反过来不行。删的时候路径必须严格对齐 - 开发时可用浏览器 DevTools → Application → Cookies 确认 path/domain 是否匹配
secure 和 httponly 参数不是可选装饰,而是安全刚需
不加 secure,Cookie 就会在 HTTP 明文连接上传输;不加 httponly,前端 JS 就能读取甚至篡改敏感 Cookie(比如 session_id)。
立即学习“PHP免费学习笔记(深入)”;
- 使用场景:生产环境必须开
secure(HTTPS 下才生效),本地开发用localhost可临时关掉,但别写死在代码里 - 参数差异:
setcookie('sess', $val, $exp, '/', '', true, true)—— 第 5 个是 domain(空表示当前域),第 6 个是secure,第 7 个是httponly - 性能影响:几乎为零,但漏掉会极大增加 XSS 或中间人劫持风险
- 容易被忽略的点:PHP 7.3+ 支持
setcookie()第 8 个参数$samesite,建议设为'Lax'防 CSRF
事情说清了就结束。Cookie 看似简单,但路径、域、安全标记、输出时机这四点只要错一个,就会表现异常,而且很难一眼定位。











