PHP读取删除Cookie方法详解
想要掌握PHP中Cookie的设置、读取与删除?本文将为你详细解读。Cookie作为服务器与浏览器间的小约定,通过`setcookie()`函数设置,`$_COOKIE`超全局数组读取,设置过期时间实现删除。务必注意,`setcookie()`需在HTML输出前调用,避免"Headers already sent"错误。此外,本文还深入探讨了Cookie的安全性,包括HttpOnly、Secure、SameSite属性的应用,以及Cookie与Session的区别与选择,助你构建更安全、高效的Web应用。更有常见陷阱与最佳实践,助你避坑,提升开发效率!
PHP中操作Cookie的核心逻辑其实非常直观:设置、读取和删除。你可以把它想象成在用户浏览器里贴了个小标签,我们用setcookie()
函数来贴这个标签,通过$_COOKIE
这个PHP自带的超全局数组来查看标签内容,而撕掉标签(删除)也只是通过设置一个过去的过期时间来完成。整个过程,说白了,就是服务器和浏览器之间基于HTTP协议的一个小约定。
解决方案
在PHP中,Cookie的操作主要围绕setcookie()
函数和$_COOKIE
超全局变量展开。
1. 设置 Cookie
使用setcookie()
函数来向用户的浏览器发送一个Cookie。这个函数必须在任何实际的HTML输出之前被调用,否则会导致“Headers already sent”错误。
<?php // 设置一个名为 'user_id',值为 '12345' 的Cookie // 有效期为1小时 (time() + 3600) // 对整个网站路径 '/' 有效 // 仅在当前域名下有效 (通常省略,或明确指定) // 仅在HTTPS连接下发送 (true) // 无法通过JavaScript访问 (true),防止XSS攻击 setcookie("user_id", "12345", [ 'expires' => time() + 3600, 'path' => '/', 'domain' => '', // 通常留空,表示当前域名 'secure' => true, // 仅在HTTPS下发送 'httponly' => true, // 无法通过JS访问 'samesite' => 'Lax' // 缓解CSRF攻击 ]); // 设置一个记住用户名的Cookie,有效期更长,例如7天 setcookie("username", "john_doe", [ 'expires' => time() + (86400 * 7), // 7天 'path' => '/', 'secure' => true, 'httponly' => true, 'samesite' => 'Lax' ]); // 也可以使用传统的参数列表形式,但数组形式更清晰,尤其是在PHP 7.3+ // setcookie("user_id", "12345", time() + 3600, "/", "", true, true); echo "Cookie已设置。"; ?>
setcookie()
函数参数详解:
name
: Cookie的名称。value
: Cookie的值。expires
: Cookie的过期时间,一个Unix时间戳。如果设置为0
或省略,则Cookie在浏览器关闭时过期(会话Cookie)。path
: Cookie在服务器上的可用路径。/
表示整个域名都可用。domain
: Cookie的有效域名。为空表示当前域名。secure
: 布尔值。如果为true
,Cookie只在HTTPS连接时发送。httponly
: 布尔值。如果为true
,Cookie无法通过JavaScript访问,有助于防止XSS攻击。samesite
: (PHP 7.3+) 字符串。Lax
、Strict
、None
。用于防止CSRF攻击。Lax
是常用且安全的默认值。
2. 读取 Cookie
已设置的Cookie可以通过$_COOKIE
超全局数组来访问。
<?php // 确保在读取之前,Cookie已经被浏览器发送回来 // 这通常发生在页面加载之后,或者重定向之后 if (isset($_COOKIE["user_id"])) { $userId = $_COOKIE["user_id"]; echo "用户ID是: " . htmlspecialchars($userId); } else { echo "未找到用户ID Cookie。"; } if (isset($_COOKIE["username"])) { $username = $_COOKIE["username"]; echo "<br>用户名是: " . htmlspecialchars($username); } else { echo "<br>未找到用户名 Cookie。"; } ?>
这里需要注意一点,$_COOKIE
数组只包含浏览器在当前请求中发送过来的Cookie。如果你在一个请求中设置了Cookie,然后立即尝试读取它,在同一个请求中是读不到的,它会在下一个请求中才可用。这是一个常见的初学者误区,我当初也在这里卡过一阵。
3. 删除 Cookie
删除Cookie的本质是设置一个已经过去的过期时间。这样浏览器会立即将其视为无效并删除。
<?php // 删除名为 'user_id' 的Cookie // 注意:路径、域名等参数必须与设置时完全一致,否则无法删除 setcookie("user_id", "", [ 'expires' => time() - 3600, // 设置为过去的时间 'path' => '/', 'domain' => '', 'secure' => true, 'httponly' => true, 'samesite' => 'Lax' ]); // 删除名为 'username' 的Cookie setcookie("username", "", [ 'expires' => time() - 3600, // 设置为过去的时间 'path' => '/', 'secure' => true, 'httponly' => true, 'samesite' => 'Lax' ]); echo "Cookie已尝试删除。"; ?>
再次强调,删除Cookie时,name
、path
和domain
参数必须和设置时完全一致。如果路径或域名不匹配,浏览器会认为你在设置一个新的、无效的Cookie,而不是删除已有的。
PHP Cookie安全性如何保障?
谈到Cookie,安全性绝对是绕不过去的话题。毕竟,这些小数据片在用户浏览器里晃悠,很容易成为攻击者的目标。我个人在处理用户认证时,对Cookie的安全性总是抱着十二分的警惕。
首先,HttpOnly
属性是防止跨站脚本(XSS)攻击的利器。当一个Cookie被标记为HttpOnly
时,JavaScript代码就无法通过document.cookie
等方式访问它。这意味着即使你的网站不幸被注入了恶意的JS代码,攻击者也无法轻易窃取用户的会话Cookie,从而降低了会话劫持的风险。我通常会把所有存储会话ID或认证令牌的Cookie都设置为HttpOnly
。
其次,Secure
属性确保Cookie只在HTTPS连接下发送。这对于保护Cookie在传输过程中的机密性至关重要。如果你的网站支持HTTPS,那么所有重要的Cookie都应该设置为Secure
。想想看,如果用户在一个公共Wi-Fi下使用你的网站,而你的Cookie没有Secure
,那么他们的会话ID就可能被嗅探到,这简直是灾难。
再者,SameSite
属性是近年来对抗跨站请求伪造(CSRF)攻击的有效手段。它告诉浏览器,这个Cookie是否可以随跨站请求一起发送。
Strict
: 最严格,只有当请求是同站发起的,或者用户直接导航到目标网站时,Cookie才会被发送。这几乎完全阻止了CSRF,但可能会影响一些正常的跨站链接。Lax
: 这是一个折衷方案,也是目前很多浏览器的默认行为。它允许顶级导航(比如用户点击一个链接)和GET请求发送Cookie,但POST请求或iframe等嵌入式请求则不会发送。对于大多数用户体验来说,Lax
通常是个不错的选择。None
: 允许所有跨站请求发送Cookie,但必须同时设置Secure
属性。这主要用于需要跨站共享Cookie的场景,比如嵌入式内容或第三方认证,但安全风险也最高。 我个人倾向于优先使用Lax
,如果业务确实需要跨站,再慎重考虑None
并确保其他安全措施到位。
最后,不要在Cookie中直接存储敏感信息。密码、信用卡号、个人身份信息等,这些绝不能直接放在Cookie里。Cookie很容易被用户查看和修改,甚至被第三方工具拦截。正确的做法是,在Cookie中存储一个不敏感的、随机生成的会话ID或令牌,然后将真正的敏感数据存储在服务器端的Session中,通过这个ID进行关联。这样即使Cookie被窃取,攻击者也只能拿到一个ID,而无法直接获取到用户的敏感数据。
PHP Cookie与Session有何区别,何时选用?
这是一个老生常谈的问题,但其重要性不言而喻。Cookie和Session都是用于维持Web应用状态的机制,但它们的实现原理、存储位置和适用场景大相径庭。理解它们之间的差异,对于构建健壮安全的Web应用至关重要。
Cookie,就像我们前面说的,是服务器发送给浏览器的一小段文本信息,存储在客户端(用户的浏览器)上。它的特点是:
- 客户端存储:数据在用户本地。
- 大小限制:通常单个Cookie不超过4KB,且一个域名下的Cookie总数也有限制。
- 安全性较低:用户可以查看、修改,也可能被XSS攻击窃取。
- 无状态:HTTP协议本身是无状态的,Cookie是用来弥补这一缺陷的。
Session,则是一个服务器端的机制。当用户访问网站时,服务器会为这个用户创建一个唯一的Session,并将Session ID(通常是一个随机字符串)通过Cookie发送给浏览器。浏览器在后续请求中带上这个Session ID,服务器就能识别用户并加载对应的Session数据。它的特点是:
- 服务器端存储:实际数据存储在服务器上(文件、数据库、缓存等),浏览器只存储一个Session ID。
- 无大小限制:理论上只受服务器资源限制。
- 安全性较高:敏感数据不直接暴露给客户端。
- 有状态:通过Session ID,服务器可以追踪用户的整个会话过程。
何时选用?
我的经验是,选择哪种机制,主要取决于数据的敏感性、大小以及你希望数据存储在哪里。
选用Cookie的场景:
- 记住用户偏好:比如网站的主题颜色、语言设置、字体大小等。这些数据不敏感,且用户可能希望在下次访问时依然保持。
- “记住我”功能:通过存储一个长期有效的、加密过的令牌(而非用户密码),实现用户在一段时间内免登录。当然,这需要配合更复杂的安全策略。
- 购物车ID:在用户未登录时,存储一个临时的购物车ID,方便用户下次访问时继续购物。但具体的商品列表数据,通常还是在服务器端通过这个ID关联。
- 用户跟踪/分析:记录用户的访问路径、点击行为等,用于数据分析,但需注意隐私合规。
选用Session的场景:
- 用户登录状态:这是Session最典型的应用。一旦用户登录,服务器会创建Session并存储用户ID、权限等敏感信息,通过Session ID来维持登录状态。
- 存储敏感数据:任何不希望暴露给客户端的数据,如用户的权限列表、支付信息、临时生成的验证码等。
- 大型数据集合:如果需要存储的数据量较大,超出Cookie的限制,Session是更好的选择。
- 防止CSRF攻击:在Session中存储一个CSRF令牌,并与表单中的令牌进行比对,可以有效防止CSRF。
简单来说,Cookie是你的“小纸条”,适合记录一些不那么重要、可以公开或者方便用户修改的信息;而Session则是你的“保险柜”,用来存放那些需要严格保密、不希望被篡改的关键信息。两者经常配合使用,Session ID通过Cookie传递,共同构建了Web应用的状态管理体系。
PHP Cookie设置时有哪些常见陷阱和最佳实践?
即便Cookie看似简单,但在实际开发中,我见过不少开发者在这里踩坑。有些问题看似细微,却可能导致功能异常或安全漏洞。
常见陷阱:
setcookie()
之前有输出:这是最经典的错误。PHP的setcookie()
函数需要修改HTTP响应头。如果在此之前,你的脚本已经通过echo
、HTML代码、甚至是文件开头的BOM(Byte Order Mark)输出了任何内容,PHP就会抛出“Headers already sent”的错误。调试这种问题有时会让人抓狂,因为输出可能来自意想不到的地方。<?php echo "Hello World!"; // 这里已经有输出了 setcookie("test", "value"); // 会报错 ?>
正确做法是,确保所有
setcookie()
调用都在任何输出之前。过期时间设置不当:
- 太短:如果一个“记住我”的Cookie过期时间太短,用户会频繁被登出,体验极差。
- 太长:如果会话Cookie(非“记住我”)的过期时间过长,或者不设置(变成会话Cookie),在某些场景下可能增加安全风险,比如用户在公共电脑上忘记关闭浏览器。
- 未考虑时区:
time()
函数返回的是UTC时间戳,但用户可能位于不同时区。不过,Cookie的过期时间通常都是基于UTC来计算的,所以这通常不是大问题,但了解其原理很重要。
路径和域名不匹配:删除或更新Cookie时,
path
和domain
参数必须与设置时完全一致。如果设置了一个路径为/blog
的Cookie,而你尝试用路径/
去删除它,是不会成功的。这就像你给文件起了个名字,却用另一个名字去删除它一样。未设置
HttpOnly
和Secure
:这是安全上的疏忽。不设置HttpOnly
可能导致XSS攻击窃取Cookie,不设置Secure
则可能在HTTP连接下泄露Cookie。直接存储敏感数据:前面已经强调过,这是大忌。Cookie不是保险箱,不要放密码、支付信息等。
最佳实践:
始终在脚本顶部设置Cookie:为了避免“Headers already sent”错误,一个好的习惯是将所有
setcookie()
调用放在PHP脚本的最顶部,在任何HTML或echo
语句之前。或者,利用输出缓冲(ob_start()
)来捕获输出,并在发送HTTP头之前处理。合理设置过期时间:
- 对于会话管理,如果不是“记住我”功能,通常设置为浏览器关闭时过期,或者一个较短的固定时间(如30分钟到1小时)。
- 对于“记住我”功能,可以设置为几天到几个月,但要确保Cookie值是加密的、一次性的或带有刷新机制的令牌,而不是用户凭证。
使用数组形式的
setcookie()
参数(PHP 7.3+):这让代码更清晰,可读性更好,也方便管理各种属性。setcookie("name", "value", ['expires' => time() + 3600, 'path' => '/', 'secure' => true, 'httponly' => true, 'samesite' => 'Lax']);
为所有重要Cookie设置
HttpOnly
和Secure
:这应该是默认的安全配置。如果你的网站是HTTPS,Secure
更是必须的。利用
SameSite
属性:根据你的应用场景,选择Lax
或Strict
来增强CSRF防护。如果确实需要跨站共享Cookie(例如OAuth),再考虑None
并确保有其他CSRF防护措施。只存储非敏感标识符:Cookie中只存放Session ID、加密的令牌或用户偏好等非敏感数据。真正敏感的用户信息应该存储在服务器端的Session中。
封装Cookie操作:如果你在构建一个大型应用,考虑创建一个专门的Cookie管理类或函数。这样可以集中处理Cookie的设置、读取和删除逻辑,确保所有Cookie都遵循统一的安全和最佳实践,例如自动添加
HttpOnly
、Secure
和SameSite
属性,避免每次手动编写。这不仅提高了代码复用性,也降低了出错的概率。
以上就是《PHP读取删除Cookie方法详解》的详细内容,更多关于session,$_COOKIE,setcookie(),PHPCookie,Cookie安全的资料请关注golang学习网公众号!

- 上一篇
- 淘宝闪购重复退款怎么处理

- 下一篇
- Win10映射网络驱动器详细教程
-
- 文章 · php教程 | 41分钟前 | 回调函数 错误捕获 资源清理 register_shutdown_function PHP脚本终止
- PHP脚本结束时执行函数的几种方式
- 156浏览 收藏
-
- 文章 · php教程 | 48分钟前 | 自动化 phpmyadmin MySQL备份恢复 PHP脚本 mysqldump
- MySQL数据库备份恢复教程:轻松操作指南
- 151浏览 收藏
-
- 文章 · php教程 | 1小时前 | php 数组合并 array_merge() +运算符 array_merge_recursive()
- PHP数组合并技巧:array_merge使用方法
- 152浏览 收藏
-
- 文章 · php教程 | 1小时前 |
- LaravelAuth::user()为空解决方法
- 235浏览 收藏
-
- 文章 · php教程 | 2小时前 |
- Symfony数据库行转关联数组方法全解析
- 292浏览 收藏
-
- 文章 · php教程 | 3小时前 |
- PHP嵌套循环镜像三角形教程
- 146浏览 收藏
-
- 文章 · php教程 | 3小时前 |
- PHP删除文件的正确操作方法
- 226浏览 收藏
-
- 文章 · php教程 | 3小时前 | php 正则表达式 修饰符 preg_match 元字符
- PHP正则表达式教程与实战技巧
- 353浏览 收藏
-
- 文章 · php教程 | 3小时前 |
- Symfony表单转JSON的实用方法
- 445浏览 收藏
-
- 文章 · php教程 | 4小时前 |
- PHP数组大小写转换方法详解
- 147浏览 收藏
-
- 文章 · php教程 | 4小时前 |
- MySQL主键重复解决:INT溢出与BIGINT升级
- 331浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 499次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 484次学习
-
- PandaWiki开源知识库
- PandaWiki是一款AI大模型驱动的开源知识库搭建系统,助您快速构建产品/技术文档、FAQ、博客。提供AI创作、问答、搜索能力,支持富文本编辑、多格式导出,并可轻松集成与多来源内容导入。
- 214次使用
-
- AI Mermaid流程图
- SEO AI Mermaid 流程图工具:基于 Mermaid 语法,AI 辅助,自然语言生成流程图,提升可视化创作效率,适用于开发者、产品经理、教育工作者。
- 1008次使用
-
- 搜获客【笔记生成器】
- 搜获客笔记生成器,国内首个聚焦小红书医美垂类的AI文案工具。1500万爆款文案库,行业专属算法,助您高效创作合规、引流的医美笔记,提升运营效率,引爆小红书流量!
- 1035次使用
-
- iTerms
- iTerms是一款专业的一站式法律AI工作台,提供AI合同审查、AI合同起草及AI法律问答服务。通过智能问答、深度思考与联网检索,助您高效检索法律法规与司法判例,告别传统模板,实现合同一键起草与在线编辑,大幅提升法律事务处理效率。
- 1043次使用
-
- TokenPony
- TokenPony是讯盟科技旗下的AI大模型聚合API平台。通过统一接口接入DeepSeek、Kimi、Qwen等主流模型,支持1024K超长上下文,实现零配置、免部署、极速响应与高性价比的AI应用开发,助力专业用户轻松构建智能服务。
- 1111次使用
-
- PHP技术的高薪回报与发展前景
- 2023-10-08 501浏览
-
- 基于 PHP 的商场优惠券系统开发中的常见问题解决方案
- 2023-10-05 501浏览
-
- 如何使用PHP开发简单的在线支付功能
- 2023-09-27 501浏览
-
- PHP消息队列开发指南:实现分布式缓存刷新器
- 2023-09-30 501浏览
-
- 如何在PHP微服务中实现分布式任务分配和调度
- 2023-10-04 501浏览