mirror of
https://github.com/fofolee/uTools-Manuals.git
synced 2025-06-18 22:06:57 +08:00
362 lines
21 KiB
HTML
362 lines
21 KiB
HTML
<!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> — <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"> = ""</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"> = ""</span></span>
|
||
[, <span class="methodparam"><span class="type">string</span> <code class="parameter">$domain</code><span class="initializer"> = ""</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><html></em> 和 <em><head></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">» 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>'cookiename'</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>'/'</em> 时,Cookie 对整个域名 <code class="parameter">domain</code> 有效。
|
||
|
||
如果设置成 <em>'/foo/'</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>'www.example.com'</em>),会使 Cookie 对这个子域名和它的三级域名有效(例如 w2.www.example.com)。
|
||
要让 Cookie 对整个域名有效(包括它的全部子域名),只要设置成域名就可以了(这个例子里是 <em>'example.com'</em>)。
|
||
</p>
|
||
<p class="para">
|
||
旧版浏览器仍然在使用废弃的 <a href="http://www.faqs.org/rfcs/rfc2109" class="link external">» 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"><?php<br />$value </span><span style="color: #007700">= </span><span style="color: #DD0000">'something from 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">, </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">, </span><span style="color: #0000BB">$value</span><span style="color: #007700">, </span><span style="color: #0000BB">time</span><span style="color: #007700">()+</span><span style="color: #0000BB">3600</span><span style="color: #007700">); </span><span style="color: #FF8000">/* 1 小时过期 */<br /></span><span style="color: #0000BB">setcookie</span><span style="color: #007700">(</span><span style="color: #DD0000">"TestCookie"</span><span style="color: #007700">, </span><span style="color: #0000BB">$value</span><span style="color: #007700">, </span><span style="color: #0000BB">time</span><span style="color: #007700">()+</span><span style="color: #0000BB">3600</span><span style="color: #007700">, </span><span style="color: #DD0000">"/~rasmus/"</span><span style="color: #007700">, </span><span style="color: #DD0000">"example.com"</span><span style="color: #007700">, </span><span style="color: #0000BB">1</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">?></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"><?php<br /></span><span style="color: #FF8000">// 打印一个单独的 Cookie<br /></span><span style="color: #007700">echo </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">// debug/test 查看所有 Cookie 的另一种方式<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">?></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"><?php<br /></span><span style="color: #FF8000">// 设置过期时间为一个小时前<br /></span><span style="color: #0000BB">setcookie</span><span style="color: #007700">(</span><span style="color: #DD0000">"TestCookie"</span><span style="color: #007700">, </span><span style="color: #DD0000">""</span><span style="color: #007700">, </span><span style="color: #0000BB">time</span><span style="color: #007700">() - </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">, </span><span style="color: #DD0000">""</span><span style="color: #007700">, </span><span style="color: #0000BB">time</span><span style="color: #007700">() - </span><span style="color: #0000BB">3600</span><span style="color: #007700">, </span><span style="color: #DD0000">"/~rasmus/"</span><span style="color: #007700">, </span><span style="color: #DD0000">"example.com"</span><span style="color: #007700">, </span><span style="color: #0000BB">1</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">?></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"><?php<br /></span><span style="color: #FF8000">// 设置 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">, </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">, </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">, </span><span style="color: #DD0000">"cookieone"</span><span style="color: #007700">);<br /><br /></span><span style="color: #FF8000">// 网页刷新后,打印出以下内容<br /></span><span style="color: #007700">if (isset(</span><span style="color: #0000BB">$_COOKIE</span><span style="color: #007700">[</span><span style="color: #DD0000">'cookie'</span><span style="color: #007700">])) {<br /> foreach (</span><span style="color: #0000BB">$_COOKIE</span><span style="color: #007700">[</span><span style="color: #DD0000">'cookie'</span><span style="color: #007700">] as </span><span style="color: #0000BB">$name </span><span style="color: #007700">=> </span><span style="color: #0000BB">$value</span><span style="color: #007700">) {<br /> </span><span style="color: #0000BB">$name </span><span style="color: #007700">= </span><span style="color: #0000BB">htmlspecialchars</span><span style="color: #007700">(</span><span style="color: #0000BB">$name</span><span style="color: #007700">);<br /> </span><span style="color: #0000BB">$value </span><span style="color: #007700">= </span><span style="color: #0000BB">htmlspecialchars</span><span style="color: #007700">(</span><span style="color: #0000BB">$value</span><span style="color: #007700">);<br /> echo </span><span style="color: #DD0000">"</span><span style="color: #0000BB">$name</span><span style="color: #DD0000"> : </span><span style="color: #0000BB">$value</span><span style="color: #DD0000"> <br />\n"</span><span style="color: #007700">;<br /> }<br />}<br /></span><span style="color: #0000BB">?></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 仍旧一样,
|
||
则指定的名称会被远程客户端删除。
|
||
内部的实现是:将值设置成 'deleted',并且过期时间是一年前。
|
||
</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">» RFC 6265</a></li>
|
||
<li class="member"><a href="http://www.faqs.org/rfcs/rfc2109" class="link external">» RFC 2109</a></li>
|
||
</ul>
|
||
</p>
|
||
</div>
|
||
|
||
|
||
</div></div></div></body></html> |