代替以下代码
<?php setcookie( "TestCookie", $value, time()+(60*60*24*30) ); ?>
您可以使用以下代码
<?php setcookie( "TestCookie", $value, strtotime( '+30 days' ) ); ?>
代替以下代码
<?php setcookie( "TestCookie", $value, time()+(60*60*24*30) ); ?>
您可以使用以下代码
<?php setcookie( "TestCookie", $value, strtotime( '+30 days' ) ); ?>
想要删除 Cookie?
许多人以复杂的方式执行此操作
setcookie('name', 'content', time()-3600);
但为什么您要使它如此复杂并冒着无法正常工作的风险,当客户端的时间错误时?为什么要与 time() 搞来搞去?
以下是删除 Cookie 的最简单方法
setcookie('name', 'content', 1);
就是这样。
只是一个示例,用于阐明数组选项的使用,特别是由于 Mozilla 将弃用/惩罚 SameSite = none 的使用,这是在不使用数组选项的情况下默认使用的。
<?php
$arr_cookie_options = array (
'expires' => time() + 60*60*24*30,
'path' => '/',
'domain' => '.example.com', // 为了兼容性,在前面添加点,或者使用子域
'secure' => true, // 或 false
'httponly' => true, // 或 false
'samesite' => 'None' // None || Lax || Strict
);
setcookie('TestCookie', 'The Cookie Value', $arr_cookie_options);
?>
注意,在设置“数组 Cookie”时,会为数组的每个元素设置一个单独的 Cookie。
在流量很大的网站上,这会显著增加客户端后续 HTTP 请求的大小(包括对同一域上的静态内容的请求)。
更重要的是,Cookie 规范指出浏览器只需要为每个域接受 20 个 Cookie。这个限制由 Firefox 提高到 50,由 Opera 提高到 30,但 IE6 和 IE7 仍然强制执行每个域 20 个 Cookie 的限制。超过此限制的任何 Cookie 都会要么删除旧的 Cookie,要么被浏览器忽略/拒绝。
值得一提的是:您应该避免在 Cookie 名称中使用点。
<?php
// 实际上,这将设置 'ace_fontSize' 名称:
setcookie( 'ace.fontSize', 18 );
?>
这里没有明确说明的一点,让我困惑了一段时间,那就是域名必须包含至少两个点(.),因此 'localhost' 无效,浏览器将拒绝设置 Cookie!相反,对于 localhost,您应该使用 false。
要使您的代码在 localhost 和正常域名上都能正常工作,您可以执行以下操作
<?php
$domain = ($_SERVER['HTTP_HOST'] != 'localhost') ? $_SERVER['HTTP_HOST'] : false;
setcookie('cookiename', 'data', time()+60*60*24*365, '/', $domain, false);
?>
由于 " PHPSESSID " cookie 的 " sameSite " 属性设置为 " none " 或无效值,且没有 " secure " 属性,它将很快被拒绝。要详细了解 "sameSite" 属性,请访问 https://mdn.org.cn/docs/Web/HTTP/Headers/Set-Cookie/SameSite.
<?php
ini_set("session.cookie_secure", 1);
session_start();
我的 PHP 代码 ....
?>
注意:如果你使用 URL RewriteRules 将类似 domain.com/bla/stuf/etc 的内容转换成参数,那么在设置 cookie 时可能会遇到问题。
至少在我的设置中,参数的更改会导致 cookie 不再存在。
解决方法很简单:指定域。"/" 通常可以正常工作。
如果你想删除域中所有 cookie,你可能想使用
<?php $_SERVER['HTTP_COOKIE'] ?>
而不是
<?php $_COOKIE ?>
来确定 cookie 名称。
如果 cookie 名称采用数组表示法,例如:user[username]
那么 PHP 会在 $_COOKIE 中自动创建一个相应的数组。相反,请使用 $_SERVER['HTTP_COOKIE'],因为它反映了实际的 HTTP 请求头。
<?php
// 删除 cookie
if (isset($_SERVER['HTTP_COOKIE'])) {
$cookies = explode(';', $_SERVER['HTTP_COOKIE']);
foreach($cookies as $cookie) {
$parts = explode('=', $cookie);
$name = trim($parts[0]);
setcookie($name, '', time()-1000);
setcookie($name, '', time()-1000, '/');
}
}
?>
请注意,$_COOKIE 变量不会保存具有相同名称的多个 cookie。在同一个主机上设置两个具有相同名称的 cookie 是合法的,前提是子域不同。
<?php
setcookie("testcookie", "value1hostonly", time(), "/", ".example.com", 0, true);
setcookie("testcookie", "value2subdom", time(), "/", "subdom.example.com", 0, true);
?>
浏览器下次请求时,$_SERVER['HTTP_COOKIE'] 变量中将包含这两个 cookie,但 $_COOKIE 变量中只会有其中一个。对 subdom.example.com 的请求将包含这两个 cookie,而对 example.com 或 www.example.com 的请求只会发送值为 "value1hostonly" 的 cookie。
<?php
$kaker = explode(";", $_SERVER['HTTP_COOKIE']);
foreach($kaker as $val){
$k = explode("=", $val);
echo trim($k[0]) . " => " . $k[1];
}
// 输出
testcookie => value1hostonly
testcookie => value2subdom
?>
cookie 名称中的句点 (如 user.name) 似乎在 $_COOKIE 数组中显示为下划线 (因此为 user_name)。这意味着,例如,必须使用 $_COOKIE["user_name"] 来读取使用 setcookie("user.name" ...) 设置的 cookie,这已经相当令人困惑了。
此外,变量 $_COOKIE["user_name"] 将保留由 setcookie("user.name" ...) 设置的值,无论调用多少次 setcookie("user_name" ...) 也不会改变此值。这可以通过清除 "user.name" cookie 来轻松解决,但可能需要一段时间才能意识到这一点,因为 $_COOKIE 中只有 "user_name"。
希望这能为某人节省一些时间。
在任何网络浏览器中,都有一种非常常用的选项 "打开之前的窗口和标签页",它默认情况下是禁用的,但许多人会启用它。
当此选项处于活动状态时,网络浏览器在关闭并重新打开时,不会执行终止并启动新会话的操作,而是会保存并恢复当前会话,以及会话 cookie 和 sessionStorage。
与预期相反,会话 cookie 和 sessionStorage 可以在很长一段时间内保持有效,直到用户在关闭网络浏览器之前关闭标签页。
如果你希望 cookie (例如带时间偏移量的 cookie) 确保具有较短的生存期,则应该明确指定此较短的生存期,而不是依赖于会话 cookie 的自删除功能。
以下代码片段将 abdullah 和 Charles Martin 的示例组合成一个功能强大的组合函数(并修复了至少一个 bug)。
<?php
function set_cookie_fix_domain($Name, $Value = '', $Expires = 0, $Path = '', $Domain = '', $Secure = false, $HTTPOnly = false)
{
if (!empty($Domain))
{
// 修复域以接受带和不带 'www.' 的域。
if (strtolower(substr($Domain, 0, 4)) == 'www.') $Domain = substr($Domain, 4);
$Domain = '.' . $Domain;
// 删除端口信息。
$Port = strpos($Domain, ':');
if ($Port !== false) $Domain = substr($Domain, 0, $Port);
}
header('Set-Cookie: ' . rawurlencode($Name) . '=' . rawurlencode($Value)
. (empty($Expires) ? '' : '; expires=' . gmdate('D, d-M-Y H:i:s', $Expires) . ' GMT')
. (empty($Path) ? '' : '; path=' . $Path)
. (empty($Domain) ? '' : '; domain=' . $Domain)
. (!$Secure ? '' : '; secure')
. (!$HTTPOnly ? '' : '; HttpOnly'), false);
}
?>
基本上,如果提供了域参数,它将被转换为支持更广泛的域。这种行为可能是也可能不是可取的(例如,根据服务器的情况,可能存在安全问题),但它使 cookie 处理变得非常方便(IMO)。