(PHP 4, PHP 5, PHP 7, PHP 8)
setcookie — 发送 Cookie
$name
, string $value
= ""
, int $expires
= 0
, string $path
= ""
, string $domain
= ""
, bool $secure
= false
, bool $httponly
= false
) : boolPHP 7.3.0 起有效的签名:
$name
, string $value
= ""
, array $options
= []
) : bool
setcookie() 定义了 Cookie,会和剩下的 HTTP 头一起发送给客户端。
和其他 HTTP 头一样,必须在脚本产生任意输出之前发送 Cookie(由于协议的限制)。
请在产生任何输出之前(包括 <html>
和 <head>
或者空格)调用本函数。
一旦设置 Cookie 后,下次打开页面时可以使用 $_COOKIE 读取。 Cookie 值同样也存在于 $_REQUEST。
» RFC 6265 提供了 setcookie() 每个参数的参考标准。
name
Cookie 名称。
value
Cookie 值。
这个值储存于用户的电脑里,请勿储存敏感信息。
比如 name
是 'cookiename'
,
可通过 $_COOKIE['cookiename'] 获取它的值。
expires
Cookie 的过期时间。
这是个 Unix 时间戳,即 Unix 纪元以来(格林威治时间 1970 年 1 月 1 日 00:00:00)的秒数。
也就是说,基本可以用 time() 函数的结果加上希望过期的秒数。
或者也可以用 mktime()。
time()+60*60*24*30
就是设置 Cookie 30 天后过期。
如果设置成零,或者忽略参数, Cookie 会在会话结束时过期(也就是关掉浏览器时)。
注意:
你可能注意到了,
expires
使用 Unix 时间戳而非Wdy, DD-Mon-YYYY HH:MM:SS GMT
这样的日期格式,是因为 PHP 内部作了转换。
path
Cookie 有效的服务器路径。
设置成 '/'
时,Cookie 对整个域名 domain
有效。
如果设置成 '/foo/'
, Cookie 仅仅对 domain
中 /foo/
目录及其子目录有效(比如 /foo/bar/
)。
默认值是设置 Cookie 时的当前目录。
domain
Cookie 的有效域名/子域名。
设置成子域名(例如 'www.example.com'
),会使 Cookie 对这个子域名和它的三级域名有效(例如 w2.www.example.com)。
要让 Cookie 对整个域名有效(包括它的全部子域名),只要设置成域名就可以了(这个例子里是 'example.com'
)。
旧版浏览器仍然在使用废弃的 » RFC 2109,
需要一个前置的点 .
来匹配所有子域名。
secure
设置这个 Cookie 是否仅仅通过安全的 HTTPS 连接传给客户端。
设置成 true
时,只有安全连接存在时才会设置 Cookie。
如果是在服务器端处理这个需求,程序员需要仅仅在安全连接上发送此类 Cookie
(通过 $_SERVER["HTTPS"] 判断)。
httponly
设置成 true
,Cookie 仅可通过 HTTP 协议访问。
这意思就是 Cookie 无法通过类似 JavaScript 这样的脚本语言访问。
要有效减少 XSS 攻击时的身份窃取行为,可建议用此设置(虽然不是所有浏览器都支持),不过这个说法经常有争议。
true
或 false
options
An associative array which may have any of the keys
expires
, path
, domain
,
secure
, httponly
and samesite
.
If any other key is present an error of level E_WARNING
is generated. The values have the same meaning as described for the
parameters with the same name. The value of the samesite
element should be either None
, Lax
or Strict
.
If any of the allowed options are not given, their default values are the
same as the default values of the explicit parameters. If the
samesite
element is omitted, no SameSite cookie
attribute is set.
如果在调用本函数以前就产生了输出,setcookie() 会调用失败并返回 false
。
如果 setcookie() 成功运行,返回 true
。当然,它的意思并非用户是否已接受 Cookie。
发送 Cookie 的几个例子:
示例 #1 setcookie() 发送例子
<?php
$value = 'something from somewhere';
setcookie("TestCookie", $value);
setcookie("TestCookie", $value, time()+3600); /* 1 小时过期 */
setcookie("TestCookie", $value, time()+3600, "/~rasmus/", "example.com", 1);
?>
注意:在发送 Cookie 时,值的部分会被自动 urlencode 编码。收到 Cookie 时,会自动解码,并赋值到可变的 Cookie 名称上。 如果不想被编码,可以使用 setrawcookie() 代替。 在脚本里查看我们的测试 Cookie 的内容,使用下面的一个例子:
<?php
// 打印一个单独的 Cookie
echo $_COOKIE["TestCookie"];
// debug/test 查看所有 Cookie 的另一种方式
print_r($_COOKIE);
?>
示例 #2 setcookie() 删除例子
要删除一个 Cookie,应该设置过期时间为过去,以触发浏览器的删除机制。 下面的例子展示了如何删除上个例子里的 Cookie:
<?php
// 设置过期时间为一个小时前
setcookie("TestCookie", "", time() - 3600);
setcookie("TestCookie", "", time() - 3600, "/~rasmus/", "example.com", 1);
?>
示例 #3 setcookie() 和数组
通过带 array 标记的 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
注意: Using separator characters such as
[
and]
as part of the cookie name is not compliant to RFC 6265, section 4, but supposed to be supported by user agents according to RFC 6265, section 5.
版本 | 说明 |
---|---|
7.3.0 |
An alternative signature supporting an options
array has been added. This signature supports also setting of the
SameSite cookie attribute.
|
注意:
要在调用本函数前输出内容,可以使用输出缓冲:让输出的内容在服务器里缓冲起来, 直至真正发送给浏览器。 可在脚本里调用 ob_start() 和 ob_end_flush(), 或设置
output_buffering
php.ini 或服务器配置文件里的配置指令。
注意避坑:
expires
参数设置的。
直接调用 print_r($_COOKIE);
调试检测 Cookie 是个很好的方式。
false
,并且其他参数和上次调用 setcookie 仍旧一样,
则指定的名称会被远程客户端删除。
内部的实现是:将值设置成 'deleted',并且过期时间是一年前。
false
会导致 Cookie 被删除,所以要避免使用布尔值。
代替方式:0 是 false
,1 是 true
。
多次调用 setcookie() 会按调用顺序执行。