php设置cookie必须在任何输出前调用setcookie()或header();支持基础设置、手动头发送、数组模拟、安全删除及secure/httponly/samesite等安全参数配置。

在PHP中设置Cookie时,必须确保在任何输出发送到浏览器之前调用setcookie()函数,否则会因HTTP头已发送而失败。以下是实现Cookie设置与管理的具体步骤:
一、使用setcookie()函数设置基础Cookie
setcookie()是PHP内置函数,用于向客户端发送HTTP Set-Cookie头,从而在浏览器中创建Cookie。该函数需在页面任何HTML或空白字符输出前执行。
1、在PHP脚本顶部(确保无echo、print、空格或BOM)调用setcookie()函数。
2、传入至少一个参数:Cookie名称,例如setcookie("user_name", "Alice")。
立即学习“PHP免费学习笔记(深入)”;
3、可选添加过期时间、路径、域名、安全标志和HttpOnly标志,例如setcookie("user_name", "Alice", time()+3600, "/", "example.com", true, true)。
4、刷新页面后,通过$_COOKIE["user_name"]即可读取该值。
二、通过header()函数手动发送Set-Cookie头
当需要更底层控制Cookie属性(如SameSite策略或自定义属性)时,可直接构造Set-Cookie响应头。此方式绕过setcookie()的封装限制,但需严格遵循RFC 6265格式。
1、确认未输出任何内容,包括空行和UTF-8 BOM。
2、使用header()发送完整Set-Cookie字符串,例如header('Set-Cookie: theme=dark; expires=' . gmdate('D, d-M-Y H:i:s T', time()+86400) . '; path=/; domain=.example.com; secure; httponly; samesite=Strict');
3、注意日期必须为GMT格式,且domain前需加点号表示子域通配。
4、多个Cookie需多次调用header(),每次仅发送一个Set-Cookie头。
三、设置数组型Cookie(多维结构模拟)
PHP不原生支持直接设置嵌套数组Cookie,但可通过序列化或命名约定将数组结构扁平化存储。该方法适用于保存用户偏好等轻量结构化数据。
1、对数组使用serialize()编码,例如$cart = ["item_id" => 101, "qty" => 2]; setcookie("cart_data", serialize($cart), time()+3600);。
2、读取时用unserialize()还原,例如$cart = isset($_COOKIE["cart_data"]) ? unserialize($_COOKIE["cart_data"]) : [];
3、替代方案:用方括号命名法,例如setcookie("user[age]", "25"); setcookie("user[name]", "Bob");,之后通过$_COOKIE["user"]自动形成关联数组(需启用register_globals已废弃,不推荐)。
4、注意:unserialize()存在反序列化漏洞风险,仅对可信数据使用;生产环境应优先选用json_encode()/json_decode()。
四、删除与过期Cookie
删除Cookie的本质是发送一个同名但过期时间为过去值的Cookie,使浏览器立即丢弃它。无法通过服务端直接清除客户端已存Cookie,只能覆盖。
1、调用setcookie()并传入相同名称、空值及过去的时间戳,例如setcookie("session_id", "", time()-3600);。
2、确保路径(path)和域名(domain)参数与原始设置完全一致,否则旧Cookie仍保留。
3、若原Cookie设定了secure或httponly,删除时也必须显式传入true,例如setcookie("token", "", time()-3600, "/", "", true, true);。
4、验证是否删除成功:刷新后检查$_COOKIE中对应键是否存在,或使用浏览器开发者工具的Application → Cookies面板确认。
五、安全设置Cookie的关键参数
默认Cookie缺乏保护机制,易受窃取或篡改。启用关键安全参数可显著降低XSS和CSRF攻击风险。
1、将secure设为true,确保Cookie仅通过HTTPS传输,例如setcookie("auth_token", "abc123", 0, "/", "", true, true);。
2、将httponly设为true,防止JavaScript访问,阻断XSS盗取,例如setcookie("session_id", "xyz789", 0, "/", "", true, true);。
3、设置samesite属性为Lax或Strict,缓解CSRF,例如在header()中写入samesite=Lax(PHP 7.3+支持setcookie()第七个参数,旧版需header())。
4、关键提示:httponly=true后,JavaScript无法读写该Cookie,但document.cookie仍会显示键名(值为空),这是正常行为。










