uTools-Manuals/docs/php/setcookie.html
2019-04-08 23:22:26 +08:00

362 lines
21 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>发送 Cookie</title>
</head>
<body class="docs"><div id="layout">
<div id="layout-content"><div id="function.setcookie" class="refentry">
<div class="refnamediv">
<h1 class="refname">setcookie</h1>
<p class="verinfo">(PHP 4, PHP 5, PHP 7)</p><p class="refpurpose"><span class="refname">setcookie</span> &mdash; <span class="dc-title">发送 Cookie</span></p>
</div>
<div class="refsect1 description" id="refsect1-function.setcookie-description">
<h3 class="title">说明</h3>
<div class="methodsynopsis dc-description">
<span class="methodname"><strong>setcookie</strong></span>
( <span class="methodparam"><span class="type">string</span> <code class="parameter">$name</code></span>
[, <span class="methodparam"><span class="type">string</span> <code class="parameter">$value</code><span class="initializer"> = &quot;&quot;</span></span>
[, <span class="methodparam"><span class="type">int</span> <code class="parameter">$expire</code><span class="initializer"> = 0</span></span>
[, <span class="methodparam"><span class="type">string</span> <code class="parameter">$path</code><span class="initializer"> = &quot;&quot;</span></span>
[, <span class="methodparam"><span class="type">string</span> <code class="parameter">$domain</code><span class="initializer"> = &quot;&quot;</span></span>
[, <span class="methodparam"><span class="type">bool</span> <code class="parameter">$secure</code><span class="initializer"> = false</span></span>
[, <span class="methodparam"><span class="type">bool</span> <code class="parameter">$httponly</code><span class="initializer"> = false</span></span>
]]]]]] ) : <span class="type">bool</span></div>
<p class="para rdfs-comment">
<span class="function"><strong>setcookie()</strong></span> 定义了 Cookie会和剩下的 HTTP 头一起发送给客户端。
和其他 HTTP 头一样,必须在脚本产生任意输出<em class="emphasis">之前</em>发送 Cookie由于协议的限制
请在产生任何输出之前(包括 <em>&lt;html&gt;</em><em>&lt;head&gt;</em> 或者空格)调用本函数。
</p>
<p class="para">
一旦设置 Cookie 后,下次打开页面时可以使用 <var class="varname"><var class="varname"><a href="reserved.variables.cookies.html" class="classname">$_COOKIE</a></var></var> 读取。
Cookie 值同样也存在于 <var class="varname"><var class="varname"><a href="reserved.variables.request.html" class="classname">$_REQUEST</a></var></var>
</p>
</div>
<div class="refsect1 parameters" id="refsect1-function.setcookie-parameters">
<h3 class="title">参数</h3>
<p class="para">
<a href="http://www.faqs.org/rfcs/rfc6265" class="link external">&raquo;&nbsp;RFC 6265</a> 提供了 <span class="function"><strong>setcookie()</strong></span> 每个参数的参考标准。
<dl>
<dt>
<code class="parameter">name</code></dt>
<dd>
<p class="para">
Cookie 名称。
</p>
</dd>
<dt>
<code class="parameter">value</code></dt>
<dd>
<p class="para">
Cookie 值。
这个值储存于用户的电脑里,请勿储存敏感信息。
比如 <code class="parameter">name</code><em>&#039;cookiename&#039;</em>
可通过 <var class="varname"><var class="varname"><a href="reserved.variables.cookies.html" class="classname">$_COOKIE['cookiename']</a></var></var> 获取它的值。
</p>
</dd>
<dt>
<code class="parameter">expire</code></dt>
<dd>
<p class="para">
Cookie 的过期时间。
这是个 Unix 时间戳,即 Unix 纪元以来(格林威治时间 1970 年 1 月 1 日 00:00:00的秒数。
也就是说,基本可以用 <span class="function"><a href="time.html" class="function">time()</a></span> 函数的结果加上希望过期的秒数。
或者也可以用 <span class="function"><a href="mktime.html" class="function">mktime()</a></span>
<em>time()+60*60*24*30</em> 就是设置 Cookie 30 天后过期。
如果设置成零,或者忽略参数, Cookie 会在会话结束时过期(也就是关掉浏览器时)。
</p>
<p class="para">
<blockquote class="note"><p><strong class="note">Note</strong>:
<p class="para">
你可能注意到了,<code class="parameter">expire</code> 使用 Unix 时间戳而非 <em>Wdy, DD-Mon-YYYY
HH:MM:SS GMT</em> 这样的日期格式,是因为 PHP 内部作了转换。
</p>
</p></blockquote>
</p>
</dd>
<dt>
<code class="parameter">path</code></dt>
<dd>
<p class="para">
Cookie 有效的服务器路径。
设置成 <em>&#039;/&#039;</em>Cookie 对整个域名 <code class="parameter">domain</code> 有效。
如果设置成 <em>&#039;/foo/&#039;</em> Cookie 仅仅对 <code class="parameter">domain</code><em>/foo/</em> 目录及其子目录有效(比如 <em>/foo/bar/</em>)。
默认值是设置 Cookie 时的当前目录。
</p>
</dd>
<dt>
<code class="parameter">domain</code></dt>
<dd>
<p class="para">
Cookie 的有效域名/子域名。
设置成子域名(例如 <em>&#039;www.example.com&#039;</em>),会使 Cookie 对这个子域名和它的三级域名有效(例如 w2.www.example.com
要让 Cookie 对整个域名有效(包括它的全部子域名),只要设置成域名就可以了(这个例子里是 <em>&#039;example.com&#039;</em>)。
</p>
<p class="para">
旧版浏览器仍然在使用废弃的 <a href="http://www.faqs.org/rfcs/rfc2109" class="link external">&raquo;&nbsp;RFC 2109</a>
需要一个前置的点 <em>.</em> 来匹配所有子域名。
</p>
</dd>
<dt>
<code class="parameter">secure</code></dt>
<dd>
<p class="para">
设置这个 Cookie 是否仅仅通过安全的 HTTPS 连接传给客户端。
设置成 <strong><code>TRUE</code></strong> 时,只有安全连接存在时才会设置 Cookie。
如果是在服务器端处理这个需求,程序员需要仅仅在安全连接上发送此类 Cookie
(通过 <var class="varname"><var class="varname"><a href="reserved.variables.server.html" class="classname">$_SERVER["HTTPS"]</a></var></var> 判断)。
</p>
</dd>
<dt>
<code class="parameter">httponly</code></dt>
<dd>
<p class="para">
设置成 <strong><code>TRUE</code></strong>Cookie 仅可通过 HTTP 协议访问。
这意思就是 Cookie 无法通过类似 JavaScript 这样的脚本语言访问。
要有效减少 XSS 攻击时的身份窃取行为,可建议用此设置(虽然不是所有浏览器都支持),不过这个说法经常有争议。
PHP 5.2.0 中添加。
<strong><code>TRUE</code></strong><strong><code>FALSE</code></strong>
</p>
</dd>
</dl>
</p>
</div>
<div class="refsect1 returnvalues" id="refsect1-function.setcookie-returnvalues">
<h3 class="title">返回值</h3>
<p class="para">
如果在调用本函数以前就产生了输出,<span class="function"><strong>setcookie()</strong></span> 会调用失败并返回 <strong><code>FALSE</code></strong>
如果 <span class="function"><strong>setcookie()</strong></span> 成功运行,返回 <strong><code>TRUE</code></strong>。当然,它的意思并非用户是否已接受 Cookie。
</p>
</div>
<div class="refsect1 examples" id="refsect1-function.setcookie-examples">
<h3 class="title">范例</h3>
<p class="para">
发送 Cookie 的几个例子:
<div class="example" id="header-register-callback.example.basic">
<p><strong>Example #1 <span class="function"><strong>setcookie()</strong></span> 发送例子</strong></p>
<div class="example-contents">
<div class="phpcode"><pre><span style="color: #000000">
<span style="color: #0000BB">&lt;?php<br />$value&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">'something&nbsp;from&nbsp;somewhere'</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">setcookie</span><span style="color: #007700">(</span><span style="color: #DD0000">"TestCookie"</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">$value</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">setcookie</span><span style="color: #007700">(</span><span style="color: #DD0000">"TestCookie"</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">$value</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">time</span><span style="color: #007700">()+</span><span style="color: #0000BB">3600</span><span style="color: #007700">);&nbsp;&nbsp;</span><span style="color: #FF8000">/*&nbsp;1&nbsp;小时过期&nbsp;&nbsp;*/<br /></span><span style="color: #0000BB">setcookie</span><span style="color: #007700">(</span><span style="color: #DD0000">"TestCookie"</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">$value</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">time</span><span style="color: #007700">()+</span><span style="color: #0000BB">3600</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">"/~rasmus/"</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">"example.com"</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">1</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">?&gt;</span>
</span>
</pre></div>
</div>
</div>
</p>
<p class="para">
注意:在发送 Cookie 时,值的部分会被自动 urlencode 编码。收到 Cookie 时,会自动解码,并赋值到可变的 Cookie 名称上。
如果不想被编码,可以使用 <span class="function"><a href="setrawcookie.html" class="function">setrawcookie()</a></span> 代替——如果你的 PHP 版本是 5 及以上。
在脚本里查看我们的测试 Cookie 的内容,使用下面的一个例子:
</p>
<p class="para">
<div class="informalexample">
<div class="example-contents">
<div class="phpcode"><pre><span style="color: #000000">
<span style="color: #0000BB">&lt;?php<br /></span><span style="color: #FF8000">//&nbsp;打印一个单独的&nbsp;Cookie<br /></span><span style="color: #007700">echo&nbsp;</span><span style="color: #0000BB">$_COOKIE</span><span style="color: #007700">[</span><span style="color: #DD0000">"TestCookie"</span><span style="color: #007700">];<br /><br /></span><span style="color: #FF8000">//&nbsp;&nbsp;debug/test&nbsp;查看所有&nbsp;Cookie&nbsp;的另一种方式<br /></span><span style="color: #0000BB">print_r</span><span style="color: #007700">(</span><span style="color: #0000BB">$_COOKIE</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">?&gt;</span>
</span>
</pre></div>
</div>
</div>
</p>
<p class="para">
<div class="example" id="example-5504">
<p><strong>Example #2 <span class="function"><strong>setcookie()</strong></span> 删除例子</strong></p>
<div class="example-contents"><p>
要删除一个 Cookie应该设置过期时间为过去以触发浏览器的删除机制。
下面的例子展示了如何删除上个例子里的 Cookie
</p></div>
<div class="example-contents">
<div class="phpcode"><pre><span style="color: #000000">
<span style="color: #0000BB">&lt;?php<br /></span><span style="color: #FF8000">//&nbsp;设置过期时间为一个小时前<br /></span><span style="color: #0000BB">setcookie</span><span style="color: #007700">(</span><span style="color: #DD0000">"TestCookie"</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">""</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">time</span><span style="color: #007700">()&nbsp;-&nbsp;</span><span style="color: #0000BB">3600</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">setcookie</span><span style="color: #007700">(</span><span style="color: #DD0000">"TestCookie"</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">""</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">time</span><span style="color: #007700">()&nbsp;-&nbsp;</span><span style="color: #0000BB">3600</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">"/~rasmus/"</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">"example.com"</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">1</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">?&gt;</span>
</span>
</pre></div>
</div>
</div>
</p>
<p class="para">
<div class="example" id="example-5505">
<p><strong>Example #3 <span class="function"><strong>setcookie()</strong></span> 和数组</strong></p>
<div class="example-contents"><p>
通过带 array 标记的 Cookie 名称,也可以把 Cookie 设置成数组。
如果有数组元素,可以把它放进 Cookie 里;
脚本接收到时Cookie 名称里的值会是一个数组:
</p></div>
<div class="example-contents">
<div class="phpcode"><pre><span style="color: #000000">
<span style="color: #0000BB">&lt;?php<br /></span><span style="color: #FF8000">//&nbsp;设置&nbsp;Cookie<br /></span><span style="color: #0000BB">setcookie</span><span style="color: #007700">(</span><span style="color: #DD0000">"cookie[three]"</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">"cookiethree"</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">setcookie</span><span style="color: #007700">(</span><span style="color: #DD0000">"cookie[two]"</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">"cookietwo"</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">setcookie</span><span style="color: #007700">(</span><span style="color: #DD0000">"cookie[one]"</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">"cookieone"</span><span style="color: #007700">);<br /><br /></span><span style="color: #FF8000">//&nbsp;网页刷新后,打印出以下内容<br /></span><span style="color: #007700">if&nbsp;(isset(</span><span style="color: #0000BB">$_COOKIE</span><span style="color: #007700">[</span><span style="color: #DD0000">'cookie'</span><span style="color: #007700">]))&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;foreach&nbsp;(</span><span style="color: #0000BB">$_COOKIE</span><span style="color: #007700">[</span><span style="color: #DD0000">'cookie'</span><span style="color: #007700">]&nbsp;as&nbsp;</span><span style="color: #0000BB">$name&nbsp;</span><span style="color: #007700">=&gt;&nbsp;</span><span style="color: #0000BB">$value</span><span style="color: #007700">)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$name&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">htmlspecialchars</span><span style="color: #007700">(</span><span style="color: #0000BB">$name</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">$value&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">htmlspecialchars</span><span style="color: #007700">(</span><span style="color: #0000BB">$value</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;</span><span style="color: #DD0000">"</span><span style="color: #0000BB">$name</span><span style="color: #DD0000">&nbsp;:&nbsp;</span><span style="color: #0000BB">$value</span><span style="color: #DD0000">&nbsp;&lt;br&nbsp;/&gt;\n"</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /></span><span style="color: #0000BB">?&gt;</span>
</span>
</pre></div>
</div>
<div class="example-contents"><p>以上例程会输出:</p></div>
<div class="example-contents screen">
<div class="cdata"><pre>
three : cookiethree
two : cookietwo
one : cookieone
</pre></div>
</div>
</div>
</p>
</div>
<div class="refsect1 changelog" id="refsect1-function.setcookie-changelog">
<h3 class="title">更新日志</h3>
<p class="para">
<table class="doctable informaltable">
<thead>
<tr>
<th>版本</th>
<th>说明</th>
</tr>
</thead>
<tbody class="tbody">
<tr>
<td>5.5.0</td>
<td>
发送给客户端的 Set-Cookie 头现在会包含 Max-Age 属性。
</td>
</tr>
<tr>
<td>5.2.0</td>
<td>
添加 <code class="parameter">httponly</code> 参数。
</td>
</tr>
</tbody>
</table>
</p>
</div>
<div class="refsect1 notes" id="refsect1-function.setcookie-notes">
<h3 class="title">注释</h3>
<blockquote class="note"><p><strong class="note">Note</strong>:
<p class="para">
要在调用本函数前输出内容,可以使用输出缓冲:让输出的内容在服务器里缓冲起来,
直至真正发送给浏览器。
可在脚本里调用 <span class="function"><a href="ob_start.html" class="function">ob_start()</a></span><span class="function"><a href="ob_end_flush.html" class="function">ob_end_flush()</a></span>
或设置 <em>output_buffering</em> <var class="filename">php.ini</var> 或服务器配置文件里的配置指令。
</p>
</p></blockquote>
<blockquote class="note"><p><strong class="note">Note</strong>:
<p class="para">
如果 PHP 指令 <a href="ini.core.html#ini.register-globals" class="link">register_globals</a>
设置成 <em>on</em>Cookie 值会自动设置成变量。
下面的例子里会存在 <var class="varname"><var class="varname">$TestCookie</var></var>
我们推荐你使用 <var class="varname"><var class="varname"><a href="reserved.variables.cookies.html" class="classname">$_COOKIE</a></var></var>
</p>
</p></blockquote>
<p class="para">
注意避坑:
<ul class="itemizedlist">
<li class="listitem">
<span class="simpara">
在页面( Cookie 可见的页面下次刷新前Cookie 不会生效。
测试 Cookie 是否已经成功设置需要在下次页面加载时、Cookie 过期前检测。
过期时间是通过 <code class="parameter">expire</code> 参数设置的。
直接调用 <em>print_r($_COOKIE);</em> 调试检测 Cookie 是个很好的方式。
</span>
</li>
<li class="listitem">
<span class="simpara">
为同一个参数再次设置 Cookie 前,必须先把它删掉。
如果参数的值是空 string 或 <strong><code>FALSE</code></strong>,并且其他参数和上次调用 setcookie 仍旧一样,
则指定的名称会被远程客户端删除。
内部的实现是:将值设置成 &#039;deleted&#039;,并且过期时间是一年前。
</span>
</li>
<li class="listitem">
<span class="simpara">
因为设置值成 <strong><code>FALSE</code></strong> 会导致 Cookie 被删除,所以要避免使用布尔值。
代替方式:<em class="emphasis">0</em><strong><code>FALSE</code></strong><em class="emphasis">1</em><strong><code>TRUE</code></strong>
</span>
</li>
<li class="listitem">
<span class="simpara">
Cookie 名称可以设置成数组名称PHP 脚本里会是数组,
但用户系统里储存的是单独分开的 Cookie。
可以考虑使用 <span class="function"><a href="explode.html" class="function">explode()</a></span> 为一个 Cookie 设置多个名称和值。
不建议将 <span class="function"><a href="serialize.html" class="function">serialize()</a></span> 用于此处,因为它会导致安全漏洞。
</span>
</li>
</ul>
</p>
<p class="simpara">
多次调用 <span class="function"><strong>setcookie()</strong></span> 会按调用顺序执行。
</p>
</div>
<div class="refsect1 seealso" id="refsect1-function.setcookie-seealso">
<h3 class="title">参见</h3>
<p class="para">
<ul class="simplelist">
<li class="member"><span class="function"><a href="header.html" class="function" rel="rdfs-seeAlso">header()</a> - 发送原生 HTTP 头</span></li>
<li class="member"><span class="function"><a href="setrawcookie.html" class="function" rel="rdfs-seeAlso">setrawcookie()</a> - 发送未经 URL 编码的 cookie</span></li>
<li class="member"><a href="features.cookies.html" class="link">Cookie 章节</a></li>
<li class="member"><a href="http://www.faqs.org/rfcs/rfc6265" class="link external">&raquo;&nbsp;RFC 6265</a></li>
<li class="member"><a href="http://www.faqs.org/rfcs/rfc2109" class="link external">&raquo;&nbsp;RFC 2109</a></li>
</ul>
</p>
</div>
</div></div></div></body></html>