设置cookie永不过期

241

查看PHP设置Cookie的文档,我发现可以设置Cookie的过期时间。你可以将Cookie设置为在浏览器会话结束时或在未来的某个时间过期,但我没有找到一种方法可以将Cookie设置为永不过期。这是否可能,并且如何实现?


14
为什么这是一件糟糕的事情? - brainimus
2
根据Cookie规范,这是不可能的。它不能被设置为永不过期。 - Sarfraz
2
您可以使用 $cookie->setMaxAge(2147483647);,该值晚于2080年,并且在32位和64位上均可使用,具体请参考 https://github.com/delight-im/PHP-Cookie - caw
14个回答

312
所有的cookie都会根据cookie规范过期,所以这不是PHP的限制。
请使用一个很远的未来日期。例如,设置一个十年后过期的cookie:
setcookie(
  "CookieName",
  "CookieValue",
  time() + (10 * 365 * 24 * 60 * 60)
);

请注意,如果您在32位PHP中设置一个超过2038年的日期,数字将会循环回来,并且您将得到一个立即过期的cookie。
编辑:截至2023年,遵守最大日期取决于Web浏览器。从Chrome M104版本(2022年8月)开始,cookie不能再设置超过400天的过期日期。

16
请注意,当2018年到来时,如果我们不使用64位的PHP,这将导致32位整数溢出,并将作为接近零的时间发送给客户端。(目前在PHP上发生了25年Cookie的情况。) - Riking
119
希望在2018年(距离现在只有5年)回顾这些评论时会很有趣,看到每个人都紧急实施Y2018升级,然后在20年后的2038年再次进行。希望到那时我们已经全部跳过到64位系统,这样将来2920亿年的12月4日星期日就不会再出现这个问题了。除非我死之前我们达成了“奇点”,否则我认为我不必担心这个问题。 - shaunhusain
75
如果一个人在2037年仍在使用现在所用的同一台电脑,那就太可悲了! - Abela
41
我正在2018年阅读这篇文章,一开始有点慌,但随后意识到自己没事。 - The Interloper
31
大家好,作为一名时空旅行者,我从2019年的遥远时空与你们交流。我们的星球已经发生了很大的变化,我们正在寻找宇宙中的地方来拯救我们的物种。与此同时,我们仍在使用饼干。 - Tim van Uum
显示剩余16条评论

116

最大值:2147483647

setcookie("CookieName", "CookieValue", 2147483647);

为避免整数溢出,时间戳应设置为:
2^31 - 1 = 2147483647 = 2038-01-19 04:14:07

设置较高的值可能会导致旧版浏览器出现问题。
另请参阅有关Cookies的RFC
Max-Age=value
  OPTIONAL.  The value of the Max-Age attribute is delta-seconds,
  the lifetime of the cookie in seconds, a decimal non-negative
  integer.  To handle cached cookies correctly, a client SHOULD
  calculate the age of the cookie according to the age calculation
  rules in the HTTP/1.1 specification [RFC2616].  When the age is
  greater than delta-seconds seconds, the client SHOULD discard the
  cookie.  A value of zero means the cookie SHOULD be discarded
  immediately.

并且RFC 2616, 14.6 Age

如果缓存接收到一个大于它能表示的最大正整数的值,或者任何一个年龄计算溢出,它必须传输一个Age头,其值为2147483648(2^31)。

http://www.faqs.org/rfcs/rfc2616.html


1
非常详细!感谢您提供的好参考。 - kevinarpe

44

设置远期绝对时间:

setcookie("CookieName", "CookieValue", 2147483647);

如推荐答案所建议的那样,最好使用绝对时间而不是相对于现在计算。

与32位系统兼容的最大值为:

2147483647 = 2^31 = ~year 2038

25
20亿很容易记住,但是永久使用的理想数字应该是2^31-1=2147483647,对应于2038年1月。这是为了避免整数溢出而设置的2038年问题的最大值,正如@John所说的那样。 - David
回顾2023年,有没有一个网站可以检查32位硬件的市场份额(实际使用情况)?因为2038年正在逼近,即使IE也被弃用了!我现在有点怀疑是否还有人会使用这样老旧的计算机或新的物联网设备(通常是32位)来上网。但我知道许多实验室和医院仍然连接着旧PC到互联网,尽管用户被警告不要使用与网络相关的功能。 - jimmymcheung

16

由于我的特权,我不能在第一篇帖子中发表评论,因此只能在此处发表。

在设置比当前日期提前20年建议的正确答案时,应考虑到2038年Unix问题

如果您使用的浏览器或版本存在问题,则在2018年1月19日的cookie加上(20年)的时间可能会遇到2038问题。


6

你能不能说一个无限循环,cookie的过期时间设置为当前日期+1,这样它永远不会到达应该过期的日期,因为它总是明天?虽然有点过度设计,但只是这样说而已。


1
其实他说的有道理。只需使用适当的“闲置期”(例如3个月),然后在每个请求中使用该期限刷新cookie是有意义的。 - Stijn de Witt
@StijndeWitt 或者只设置10年。然后如果用户在10年内访问,更新它... - Jez

6
自从链接这里发布以来,Chrome浏览器的Cookie最长存活时间为400天。由于Chrome浏览器目前非常流行,所以我建议将Cookie的过期时间设置在400天或更短的时间内。
如果您不想点击链接,总结如下:
当Cookie设置了Expires/Max-Age属性时,其值现在将被限制在未来不超过400天。之前,没有限制,Cookie可以在未来多个千年后过期。

1
是的,截至2022年底,对于这个问题的最佳答案基本上已经变成“只需将其设置为400天”,如果您希望它尽可能长时间地持续。虽然将其设置更长时间也没有什么损害,因为浏览器会将其减少到这个时间。但是,现在更重要的是解决刷新cookie的问题,因为即使用户不断使用网站,每过一年多一点就自动注销所有人也不是期望的行为! - Snor

5

虽然完全不可能,但你可以采用类似Google的方法,将cookie设置为在2038年1月17日或其他同样遥远的日期过期。

实际上,你最好将cookie设置为10年或60*60*24*365*10秒,这样它可以存活在大多数计算机上。


2
那样做可以一直运行到2028年初,届时您将会溢出该值,从而导致Cookie停止工作。最好使用绝对值。 - davidjbullock
1
假设他的代码在2028年仍将在过时的机器上运行...不知何故,我更担心每个人都会忘记更新固定日期...软件往往比硬件更持久。 - Stijn de Witt

4
如果您想将数据永久地保存在客户端机器上,或者至少在浏览器缓存完全清空之前,可以使用JavaScript本地存储技术:localStorage。请勿使用会像最大生存期为零的cookie一样被清除的session storage。详情请参见:https://developer.mozilla.org/en-US/docs/DOM/Storage#localStorage

在读取服务器端数据时,不能考虑使用localStorage。 - WhiteHorse

2

从人生的不可预测性出发,我避免使用“永远”和“从不”这两个词。

使用有符号的32位整数可以存储自1970年1月1日以来的最新时间是2038年1月19日星期二03:14:07(即距离1970年1月1日231-1=2,147,483,647秒)。这个限制被称为2038年问题

setCookie("name", "value", strtotime("2038-01-19 03:14:07"));

1
你可以设置一个远离日期的时间作为cookie创建日期,如下所示:
var Cookie_expiry = new Date();
Cookie_expiry.setDate(Cookie_expiry.getDate()+10e5);   
// expiry date of cookie is set to be practically infinite (~ 4000 years)
setCookie('token', 'token_value', {expires: Cookie_expiry});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接