
在 Laravel 等 PHP 项目中,开发者常利用 Carbon 库来处理日期和时间。一个常见的场景是设置 HTTP Cookie 的过期时间。例如,以下代码尝试使用 Carbon 设置一个带有特定时区(如 Europe/London)的过期时间,并将其转换为 Unix 时间戳传递给 setcookie 函数:
/**
* 创建一个Cookie
*
* @param string $name Cookie名称
* @param string $value Cookie值
* @param int $expires 过期时间(分钟)
*/
public function createCookie($name, $value, $expires = 60)
{
// 期望:在 Europe/London 时区下,当前时间加 $expires 分钟后过期
$expiry = Carbon::now()->addMinutes($expires)->setTimezone('Europe/London');
// 将 Carbon 对象转换为 Unix 时间戳
setcookie($name, $value, $expiry->timestamp);
}然而,当在浏览器中检查这个 Cookie 的过期时间时,开发者可能会发现它仍然显示为协调世界时(UTC)格式,而非预期的 Europe/London 时区。这常常导致一个误解:认为 Carbon::setTimezone() 没有生效,或者 setcookie 函数忽略了时区设置。
要理解这一现象,首先需要明确 Unix 时间戳的定义。Unix 时间戳(Unix Epoch)是指自协调世界时(UTC)1970年1月1日00:00:00以来经过的秒数。它是一个整数值,代表了一个全球统一的、与任何特定时区无关的绝对时间点。
Carbon 库中的 $timestamp 属性正是这一概念的体现。根据 CarbonInterface 的定义,$timestamp 属性表示“自 Unix 纪元以来的秒数”。无论 Carbon 对象内部设置了哪个时区,其 timestamp 属性返回的都是该时间点在 UTC 时间下的秒数。setTimezone() 方法会改变 Carbon 对象在格式化输出或进行日期计算时的表现,但它不会改变该时间点所对应的 Unix 时间戳的底层值。例如:
立即学习“PHP免费学习笔记(深入)”;
$nowUtc = Carbon::now('UTC');
$nowLondon = Carbon::now('Europe/London');
echo $nowUtc->timestamp; // 输出:1678886400 (示例值)
echo $nowLondon->timestamp; // 输出:1678886400 (与 UTC 时间戳相同)尽管 $nowLondon 对象在显示时会根据 Europe/London 时区进行调整,但其 timestamp 属性的值与 UTC 时区的 Carbon 对象是完全一致的,因为它代表的是同一个绝对时间点。
PHP 的 setcookie 函数在处理 expires 参数时,明确要求传入一个 Unix 时间戳。根据 PHP 官方文档:
黑色全屏自适应的H5模板 HTML5的设计目的是为了在移动设备上支持多媒体。新的语法特征被引进以支持这一点,如video、audio和canvas 标记。HTML5还引进了新的功能,可以真正改变用户与文档的交互方式,包括: 新的解析规则增强了灵活性 淘汰过时的或冗余的属性 一个HTML5文档到另一个文档间的拖放功能 多用途互联网邮件扩展(MIME)和协议处理程序注册 在SQL数据库中存
56
expires Cookie 的过期时间。这是一个 Unix 时间戳,表示自纪元以来的秒数。换句话说,您很可能使用 time() 函数加上您希望它过期的秒数来设置它。或者您可以使用 mktime()。time()+60*60*24*30 将把 cookie 设置为 30 天后过期。如果设置为 0 或省略,则 cookie 将在会话结束时(浏览器关闭时)过期。注意: 您可能会注意到 expires 参数采用 Unix 时间戳,而不是日期格式 Wdy, DD-Mon-YYYY HH:MM:SS GMT,这是因为 PHP 在内部进行了这种转换。
这明确指出,即使 HTTP 协议要求 Set-Cookie 响应头中的 Expires 属性采用 Wdy, DD-Mon-YYYY HH:MM:SS GMT 这种特定格式,PHP 也会内部将传入的 Unix 时间戳转换为这种格式。这里的 GMT(格林尼治标准时间)在大多数上下文中可以视为与 UTC 等同。因此,浏览器中显示的 GMT 或 UTC 格式的过期时间是 PHP 内部转换后的结果,而非 Carbon 的 setTimezone 操作被忽略。
综上所述,当您使用 Carbon 对象生成 Unix 时间戳并将其传递给 setcookie 函数时,无论 Carbon 对象内部设置了哪个时区,setcookie 最终都会将这个 Unix 时间戳(一个无时区的 UTC 值)转换为 GMT/UTC 格式的日期字符串发送给浏览器。浏览器接收并显示这个 GMT/UTC 格式的过期时间是完全符合预期的行为。
因此,如果您的目标是设置一个精确的过期时间点,并且希望在 PHP 内部进行时区感知计算,Carbon::setTimezone() 是有用的。但当您将结果传递给 setcookie 时,请记住 expires 参数只关心绝对的 Unix 时间戳,其在浏览器中的最终显示将是 GMT/UTC。这种行为是设计使然,并非错误。
总结要点:
理解这些基本原理,有助于避免在处理日期和时间时产生不必要的困惑,并能更有效地利用 Carbon 和 PHP 的内置功能。
以上就是理解PHP setcookie 过期时间与Carbon时区设置的交互的详细内容,更多请关注php中文网其它相关文章!
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号