(PHP 4, PHP 5, PHP 7, PHP 8)
setcookie — 发送 Cookie
$name,$value = "",$expires_or_options = 0,$path = "",$domain = "",$secure = false,$httponly = false自 PHP 7.3.0 起可用的替代签名(不支持命名参数):
setcookie() 用于定义 Cookie,会和其它 HTTP header 一起发送给客户端。和其他 HTTP header 一样,Cookie
必须在脚本输出任意内容之前发送 Cookie(这是协议限制)。该函数必须在输出任何内容(包括
<html> 和 <head> 或者任何空白字符)之前调用。
一旦设置 Cookie 后,下次打开页面时可以使用 $_COOKIE 读取。Cookie 值同样也存在于 $_REQUEST。
» RFC 6265 提供了 setcookie() 每个参数的参考标准。
namevaluename 是 'cookiename',可通过
$_COOKIE['cookiename'] 获取它的值。
expires_or_optionstime()+60*60*24*30
就是设置 Cookie 30 天后过期。还有一种选择就是使用 mktime()
函数。如果设置为 0 或者忽略,Cookie 会在会话结束时过期(关掉浏览器时)。
注意:
expires_or_options使用 Unix 时间戳而非Wdy, DD-Mon-YYYY HH:MM:SS GMT这样的日期格式,是因为 PHP 内部作了转换。
path'/' 时,Cookie 对整个域名
domain 有效。如果设置成 '/foo/',Cookie
仅仅对 domain 中 /foo/
目录及其子目录有效(比如 /foo/bar/)。默认值是设置 Cookie 时的当前目录。
domain'www.example.com'),会使
Cookie 对这个子域名和它的三级域名有效(例如 w2.www.example.com)。要让 Cookie
对整个域名有效(包括它的全部子域名),只要设置成域名就可以了(这个示例里是 'example.com')。
旧版浏览器仍然在使用废弃的 » RFC 2109,需要一个前置的点
. 来匹配所有子域名。
securetrue 时,只有安全连接存在时才会设置
Cookie。如果是在服务器端处理这个需求,程序员需要仅仅在安全连接上发送此类 Cookie(通过
$_SERVER["HTTPS"] 判断)。
httponlytrue,Cookie 仅可通过 HTTP 协议访问。这意思就是 Cookie 无法通过类似 JavaScript
这样的脚本语言访问。要有效减少 XSS 攻击时的身份窃取行为,可建议用此设置(虽然不是所有浏览器都支持),不过这个说法经常有争议。
true 或 false
optionsexpires、path、domain、secure、httponly 和
samesite。如果存在其它的键,会生成 E_WARNING
级别的错误。这些值的含义跟同名参数的描述相同。samesite 元素的值应该是
None、Lax 或
Strict。如果没有指定任何允许的选项,它们的默认值与显式参数的默认值相同。如果省略
samesite 元素,则不设置 SameSite cookie 属性。
注意: 要设置一个包含不在列出的关键字中的属性的 Cookie,使用 header()。
注意: 若
samesite为"None",则必须同时启用secure,否则客户端将阻止该 Cookie。
| 版本 | 说明 |
|---|---|
| 8.2.0 |
Cookie 的日期格式现在为 'D, d M Y H:i:s \G\M\T';
以前是 'D, d-M-Y H:i:s T'。
|
| 7.3.0 |
新增对替代签名 options 数组的支持。此签名还支持 SameSite cookie 属性的设置。
|
下列示例的效果可通过浏览器开发者工具中的 Cookie 列表(通常位于 Storage 或 Application 标签页)进行观察。
示例 #1 setcookie() 发送示例
<?php
$value = 'something from somewhere';
// 设置“会话 Cookie”,在浏览器关闭时失效
setcookie("TestCookie", $value);
// 设置一小时后失效的 Cookie
setcookie("TestCookie", $value, time()+3600);
// 设置仅适用于特定域名下特定路径的 Cookie
// 注意所使用的域名应与站点域名一致
setcookie("TestCookie", $value, time()+3600, "/~rasmus/", "example.com", true);
?>注意,Cookie 的值部分会由 PHP 自动进行 URL 编码和解码。若要避免此行为,可改用 setrawcookie()。
要在后续请求中查看上述示例所设置的 Cookie 内容:
<?php
// 打印一个单独的 Cookie
echo $_COOKIE["TestCookie"];
// debug/test 查看所有 Cookie 的另一种方式
print_r($_COOKIE);
?>示例 #2 setcookie() 删除示例
要删除 Cookie,需将过期时间设为过去的时间值(但不能设为零,因为零专用于会话 Cookie)。
删除前例中设置的 Cookie:
<?php
// 设置过期时间为一个小时前
setcookie("TestCookie", "", time() - 3600);
setcookie("TestCookie", "", time() - 3600, "/~rasmus/", "example.com", 1);
?>示例 #3 setcookie() 和数组
在 Cookie 名称中使用数组表示法,可设置“Cookie 数组”。其效果是为数组中的每个元素分别设置一个 Cookie;当脚本接收到 Cookie 时,所有值会被合并到一个以该 Cookie 名称命名的数组中:
<?php
// 设置 Cookie
setcookie("cookie[three]", "cookiethree");
setcookie("cookie[two]", "cookietwo");
setcookie("cookie[one]", "cookieone");
// 网页刷新后,打印出以下内容
if (isset($_COOKIE['cookie'])) {
foreach ($_COOKIE['cookie'] as $name => $value) {
$name = htmlspecialchars($name);
$value = htmlspecialchars($value);
echo "$name : $value <br />\n";
}
}
?>以上示例会输出:
three : cookiethree two : cookietwo one : cookieone
注意: 使用
[和]分隔符作为 cookie 名称的一部分不符合 RFC 6265 第 4 节。但根据 RFC 6265 第 5 节应该由 user agent 支持。
注意: 可使用输出缓冲机制,使脚本在调用此函数前产生输出。会缓冲所有输出,直到冲刷缓冲(手动冲刷或脚本执行结束时自动刷新)。实现方式是在脚本中调用 ob_start() 和 ob_end_flush(),或在 php.ini 或服务器配置文件中启用
output_buffering配置项。
注意避坑:
expires_or_options 参数设置的。
直接调用 print_r($_COOKIE); 调试检测 Cookie 是个很好的方式。
value 的值是空 string,并且其他参数和上次调用 setcookie() 仍旧一样,
则指定的名称会被远程客户端删除。
内部的实现是:将值设置成 'deleted',且过去的过期时间。
false 会导致 Cookie 被删除,所以不应该使用布尔值。代替方式:0 是 false,1 是 true。
多次调用 setcookie() 会按调用顺序执行。