- PHP Manual
- 网络 函数
- 发送 Cookie
setcookie
(PHP 4, PHP 5, PHP 7)
setcookie — 发送 Cookie
说明
setcookie
( string $name
[, string $value
= ""
[, int $expire
= 0
[, string $path
= ""
[, string $domain
= ""
[, bool $secure
= false
[, bool $httponly
= false
]]]]]] ) : bool
setcookie() 定义了 Cookie,会和剩下的 HTTP 头一起发送给客户端。
和其他 HTTP 头一样,必须在脚本产生任意输出之前发送 Cookie(由于协议的限制)。
请在产生任何输出之前(包括 <html>
和 <head>
或者空格)调用本函数。
一旦设置 Cookie 后,下次打开页面时可以使用 $_COOKIE
读取。
Cookie 值同样也存在于 $_REQUEST
。
参数
» RFC 6265 提供了 setcookie() 每个参数的参考标准。
name
Cookie 名称。
value
Cookie 值。 这个值储存于用户的电脑里,请勿储存敏感信息。 比如
name
是'cookiename'
, 可通过$_COOKIE['cookiename']
获取它的值。expire
Cookie 的过期时间。 这是个 Unix 时间戳,即 Unix 纪元以来(格林威治时间 1970 年 1 月 1 日 00:00:00)的秒数。 也就是说,基本可以用 time() 函数的结果加上希望过期的秒数。 或者也可以用 mktime()。
time()+60*60*24*30
就是设置 Cookie 30 天后过期。 如果设置成零,或者忽略参数, Cookie 会在会话结束时过期(也就是关掉浏览器时)。Note:
你可能注意到了,
expire
使用 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 攻击时的身份窃取行为,可建议用此设置(虽然不是所有浏览器都支持),不过这个说法经常有争议。 PHP 5.2.0 中添加。true
或false
返回值
如果在调用本函数以前就产生了输出,setcookie() 会调用失败并返回 false
。
如果 setcookie() 成功运行,返回 true
。当然,它的意思并非用户是否已接受 Cookie。
范例
发送 Cookie 的几个例子:
Example #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() 代替——如果你的 PHP 版本是 5 及以上。 在脚本里查看我们的测试 Cookie 的内容,使用下面的一个例子:
<?php// 打印一个单独的 Cookieecho $_COOKIE["TestCookie"];// debug/test 查看所有 Cookie 的另一种方式print_r($_COOKIE);?>
Example #2 setcookie() 删除例子
要删除一个 Cookie,应该设置过期时间为过去,以触发浏览器的删除机制。 下面的例子展示了如何删除上个例子里的 Cookie:
<?php// 设置过期时间为一个小时前setcookie("TestCookie", "", time() - 3600);setcookie("TestCookie", "", time() - 3600, "/~rasmus/", "example.com", 1);?>
Example #3 setcookie() 和数组
通过带 array 标记的 Cookie 名称,也可以把 Cookie 设置成数组。 如果有数组元素,可以把它放进 Cookie 里; 脚本接收到时,Cookie 名称里的值会是一个数组:
<?php// 设置 Cookiesetcookie("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
更新日志
版本 | 说明 |
---|---|
5.5.0 | 发送给客户端的 Set-Cookie 头现在会包含 Max-Age 属性。 |
5.2.0 | 添加 httponly 参数。
|
注释
Note:
要在调用本函数前输出内容,可以使用输出缓冲:让输出的内容在服务器里缓冲起来, 直至真正发送给浏览器。 可在脚本里调用 ob_start() 和 ob_end_flush(), 或设置
output_buffering
php.ini
或服务器配置文件里的配置指令。
Note:
如果 PHP 指令 register_globals 设置成
on
,Cookie 值会自动设置成变量。 下面的例子里会存在$TestCookie
。 我们推荐你使用$_COOKIE
。
注意避坑:
- 在页面( Cookie 可见的页面)下次刷新前,Cookie 不会生效。 测试 Cookie 是否已经成功设置,需要在下次页面加载时、Cookie 过期前检测。 过期时间是通过
expire
参数设置的。 直接调用print_r($_COOKIE);
调试检测 Cookie 是个很好的方式。 - 为同一个参数再次设置 Cookie 前,必须先把它删掉。 如果参数的值是空 string 或
false
,并且其他参数和上次调用 setcookie 仍旧一样, 则指定的名称会被远程客户端删除。 内部的实现是:将值设置成 'deleted',并且过期时间是一年前。 - 因为设置值成
false
会导致 Cookie 被删除,所以要避免使用布尔值。 代替方式:0 是false
,1 是true
。 - Cookie 名称可以设置成数组名称,PHP 脚本里会是数组, 但用户系统里储存的是单独分开的 Cookie。 可以考虑使用 explode() 为一个 Cookie 设置多个名称和值。 不建议将 serialize() 用于此处,因为它会导致安全漏洞。
多次调用 setcookie() 会按调用顺序执行。