Cookie 类
HTTP Cookie (网页 Cookie、浏览器 Cookie)是服务器发送到用户浏览器的一小段数据。浏览器可存储该数据,并在后续向同一服务器发送请求时将其回传。通常用于判断两个请求是否来自同一浏览器,例如保持用户登录状态,为无状态的 HTTP 协议记录状态信息。
Cookie 主要用于三种场景:
会话管理:登录状态、购物车、游戏分数或服务器需要记住的其他信息
个性化:用户偏好、主题和其他设置
追踪:记录和分析用户行为
为高效地向浏览器发送 Cookie,CodeIgniter 提供 CodeIgniter\Cookie\Cookie 类来抽象 Cookie 交互操作。
创建 Cookie
目前可通过四种方式创建新的 Cookie 值对象。
<?php
use CodeIgniter\Cookie\Cookie;
use DateTime;
// Using the constructor
$cookie = new Cookie(
'remember_token',
'f699c7fd18a8e082d0228932f3acd40e1ef5ef92efcedda32842a211d62f0aa6',
[
'expires' => new DateTime('+2 hours'),
'prefix' => '__Secure-',
'path' => '/',
'domain' => '',
'secure' => true,
'httponly' => true,
'raw' => false,
'samesite' => Cookie::SAMESITE_LAX,
],
);
// Supplying a Set-Cookie header string
$cookie = Cookie::fromHeaderString(
'remember_token=f699c7fd18a8e082d0228932f3acd40e1ef5ef92efcedda32842a211d62f0aa6; Path=/; Secure; HttpOnly; SameSite=Lax',
false, // raw
);
// Using the fluent builder interface
$cookie = (new Cookie('remember_token'))
->withValue('f699c7fd18a8e082d0228932f3acd40e1ef5ef92efcedda32842a211d62f0aa6')
->withPrefix('__Secure-')
->withExpires(new DateTime('+2 hours'))
->withPath('/')
->withDomain('')
->withSecure(true)
->withHTTPOnly(true)
->withSameSite(Cookie::SAMESITE_LAX);
// Using the global function `cookie` which implicitly calls `new Cookie()`
$cookie = cookie('remember_token', 'f699c7fd18a8e082d0228932f3acd40e1ef5ef92efcedda32842a211d62f0aa6');
构造 Cookie 对象时,仅需 name 属性,其余均为可选。若未修改可选属性,将使用 Cookie 类中保存的默认值。
覆盖默认值
要覆盖类中当前存储的默认值,可向静态方法 Cookie::setDefaults() 传入 Config\Cookie 实例或包含默认值的数组。
<?php
use CodeIgniter\Cookie\Cookie;
use Config\Cookie as CookieConfig;
// pass in a Config\Cookie instance before constructing a Cookie class
Cookie::setDefaults(config(CookieConfig::class));
$cookie = new Cookie('login_token');
// pass in an array of defaults
$myDefaults = [
'expires' => 0,
'samesite' => Cookie::SAMESITE_STRICT,
];
Cookie::setDefaults($myDefaults);
$cookie = new Cookie('login_token');
向 Cookie::setDefaults() 传入 Config\Cookie 实例或数组会覆盖当前默认值,并在传入新默认值前一直生效。
临时更改默认值
若不希望此行为生效,仅需临时更改默认值,可利用 Cookie::setDefaults() 返回旧默认值数组的特性。
<?php
use CodeIgniter\Cookie\Cookie;
use Config\Cookie as CookieConfig;
$oldDefaults = Cookie::setDefaults(config(CookieConfig::class));
$cookie = new Cookie('my_token', 'muffins');
// return the old defaults
Cookie::setDefaults($oldDefaults);
访问 Cookie 属性
实例化后,可通过 getter 方法轻松访问 Cookie 的属性。
<?php
use CodeIgniter\Cookie\Cookie;
use DateTime;
use DateTimeZone;
$cookie = new Cookie(
'remember_token',
'f699c7fd18a8e082d0228932f3acd40e1ef5ef92efcedda32842a211d62f0aa6',
[
'expires' => new DateTime('2025-02-14 00:00:00', new DateTimeZone('UTC')),
'prefix' => '__Secure-',
'path' => '/',
'domain' => '',
'secure' => true,
'httponly' => true,
'raw' => false,
'samesite' => Cookie::SAMESITE_LAX,
],
);
$cookie->getName(); // 'remember_token'
$cookie->getPrefix(); // '__Secure-'
$cookie->getPrefixedName(); // '__Secure-remember_token'
$cookie->getExpiresTimestamp(); // UNIX timestamp
$cookie->getExpiresString(); // 'Fri, 14 Feb 2025 00:00:00 GMT'
$cookie->isExpired(); // false
$cookie->getMaxAge(); // the difference from time() to expires
$cookie->isRaw(); // false
$cookie->isSecure(); // true
$cookie->getPath(); // '/'
$cookie->getDomain(); // ''
$cookie->isHTTPOnly(); // true
$cookie->getSameSite(); // 'Lax'
// additional getter
$cookie->getId(); // '__Secure-remember_token;;/'
// when using `setcookie()`'s alternative signature on PHP 7.3+
// you can easily use the `getOptions()` method to supply the
// $options parameter
$cookie->getOptions();
不可变 Cookie
新的 Cookie 实例是 HTTP Cookie 的不可变值对象表示。因其不可变性,修改实例的任意属性不会影响原实例,修改操作 始终 返回新实例,需保留该新实例才能使用。
<?php
use CodeIgniter\Cookie\Cookie;
$cookie = new Cookie('login_token', 'admin');
$cookie->getName(); // 'login_token'
$cookie->withName('remember_token');
$cookie->getName(); // 'login_token'
$new = $cookie->withName('remember_token');
$new->getName(); // 'remember_token'
验证 Cookie 属性
HTTP Cookie 受多项规范约束,必须遵守才能被浏览器接受。因此创建或修改 Cookie 的某些属性时,会进行验证以确保符合规范。
若存在违规情况,将抛出 CookieException 异常。
验证 Name 属性
Cookie 名称可使用任意 US-ASCII 字符,但以下字符除外:
控制字符
空格或制表符
分隔符,如
( ) < > @ , ; : \ " / [ ] ? = { }
若将 $raw 参数设为 true,验证将更为严格。因为 PHP 的 setcookie() 和 setrawcookie() 会拒绝名称无效的 Cookie。此外,Cookie 名称不能为空字符串。
验证 Prefix 属性
使用 __Secure- 前缀时,Cookie 必须设置 $secure 标志为 true。若使用 __Host- 前缀,Cookie 必须满足以下条件:
$secure标志设为true$domain为空$path必须为/
验证 SameSite 属性
SameSite 属性接受三个值:
Lax:常规跨站点子请求(如向第三方网站加载图片或框架)不发送 Cookie,但用户导航到源站点时(如点击链接)会发送。
Strict:Cookie 仅在第一方上下文中发送,不会随第三方网站发起的请求一起发送。
None:Cookie 在所有上下文中发送,即响应第一方和跨源请求时均会发送。
CodeIgniter 允许将 SameSite 属性设为空字符串。传入空字符串时,将使用 Cookie 类中保存的默认 SameSite 设置。可通过上述 Cookie::setDefaults() 方法更改默认 SameSite 设置。
近期 Cookie 规范已变更,现代浏览器若未提供 SameSite 值,则默认使用 Lax。若将 SameSite 设为空字符串且默认 SameSite 也为空字符串,Cookie 将被赋予 Lax 值。
若 SameSite 设为 None,需确保 Secure 也设为 true。
写入 SameSite 属性时,Cookie 类不区分大小写地接受以上任一值。也可使用类常量简化操作。
<?php
use CodeIgniter\Cookie\Cookie;
Cookie::SAMESITE_LAX; // 'Lax'
Cookie::SAMESITE_STRICT; // 'Strict'
Cookie::SAMESITE_NONE; // 'None'
发送 Cookie
在 Response 对象的 CookieStore 中设置 Cookie 对象,框架会自动发送这些 Cookie。
使用 CodeIgniter\HTTP\Response::setCookie() 进行设置:
<?php
use CodeIgniter\Cookie\Cookie;
$response = service('response');
$cookie = new Cookie(
'remember_token',
'f699c7fd18a8e082d0228932f3acd40e1ef5ef92efcedda32842a211d62f0aa6',
[
'max-age' => 3600 * 2, // Expires in 2 hours
],
);
$response->setCookie($cookie);
也可使用 set_cookie() 辅助函数:
<?php
use CodeIgniter\Cookie\Cookie;
helper('cookie');
$cookie = new Cookie(
'remember_token',
'f699c7fd18a8e082d0228932f3acd40e1ef5ef92efcedda32842a211d62f0aa6',
[
'max-age' => 3600 * 2, // Expires in 2 hours
],
);
set_cookie($cookie);
使用 Cookie Store
备注
通常无需直接使用 CookieStore。
CookieStore 类表示 Cookie 对象的不可变集合。
从 Response 获取 Store
可从当前 Response 对象访问 CookieStore 实例。
<?php
$cookieStore = service('response')->getCookieStore();
创建 CookieStore
CodeIgniter 提供另外三种方式创建 CookieStore 新实例。
<?php
use CodeIgniter\Cookie\Cookie;
use CodeIgniter\Cookie\CookieStore;
// Passing an array of `Cookie` objects in the constructor
$store = new CookieStore([
new Cookie('login_token'),
new Cookie('remember_token'),
]);
// Passing an array of `Set-Cookie` header strings
$store = CookieStore::fromCookieHeaders([
'remember_token=me; Path=/; SameSite=Lax',
'login_token=admin; Path=/; SameSite=Lax',
]);
// using the global `cookies` function
$store = cookies([new Cookie('login_token')], false);
// retrieving the `CookieStore` instance saved in our current `Response` object
$store = cookies();
备注
使用全局 cookies() 函数时,仅当第二个参数 $getGlobal 设为 false 时才会使用传入的 Cookie 数组。
检查 Store 中的 Cookie
检查 CookieStore 实例中是否存在 Cookie 对象,可使用以下方式:
<?php
use CodeIgniter\Cookie\Cookie;
use CodeIgniter\Cookie\CookieStore;
// check if cookie is in the current cookie collection
$store = new CookieStore([
new Cookie('login_token'),
new Cookie('remember_token'),
]);
$store->has('login_token');
// check if cookie is in the current Response's cookie collection
cookies()->has('login_token');
service('response')->hasCookie('remember_token');
// using the cookie helper to check the current Response
// not available to v4.1.1 and lower
helper('cookie');
has_cookie('login_token');
获取 Store 中的 Cookie
从 Cookie 集合中获取 Cookie 实例非常简单:
<?php
use CodeIgniter\Cookie\Cookie;
use CodeIgniter\Cookie\CookieStore;
use Config\Services;
// getting cookie in the current cookie collection
$store = new CookieStore([
new Cookie('login_token'),
new Cookie('remember_token'),
]);
$store->get('login_token');
// getting cookie in the current Response's cookie collection
cookies()->get('login_token');
service('response')->getCookie('remember_token');
// using the cookie helper to get cookie from the Response's cookie collection
helper('cookie');
get_cookie('remember_token');
直接从 CookieStore 获取 Cookie 实例时,无效名称将抛出 CookieException 异常。
<?php
// throws CookieException
$store->get('unknown_cookie');
从当前 Response 的 Cookie 集合获取 Cookie 实例时,无效名称仅返回 null。
<?php
cookies()->get('unknown_cookie'); // null
从 Response 获取 Cookie 时若未提供参数,将显示 Store 中的所有 Cookie 对象。
<?php
cookies()->display(); // array of Cookie objects
// or even from the Response
service('response')->getCookies();
备注
辅助函数 get_cookie() 从当前 Request 对象而非 Response 获取 Cookie。该函数检查 $_COOKIE 数组中是否设置了该 Cookie 并立即获取。
在 Store 中添加/移除 Cookie
如前所述,CookieStore 对象不可变。需保存修改后的实例才能继续操作,原实例保持不变。
<?php
use CodeIgniter\Cookie\Cookie;
use CodeIgniter\Cookie\CookieStore;
$store = new CookieStore([
new Cookie('login_token'),
new Cookie('remember_token'),
]);
// adding a new Cookie instance
$new = $store->put(new Cookie('admin_token', 'yes'));
// removing a Cookie instance
$new = $store->remove('login_token');
备注
从 Store 移除 Cookie 不会 从浏览器中删除。若要从浏览器删除 Cookie,必须将同名空值 Cookie 放入 Store。
与当前 Response 对象中的 Store Cookie 交互时,可安全地添加或删除 Cookie,无需担心 Cookie 集合的不可变性。Response 对象会用修改后的实例替换原实例。
<?php
service('response')->setCookie('admin_token', 'yes');
service('response')->deleteCookie('login_token');
// using the cookie helper
helper('cookie');
set_cookie('admin_token', 'yes');
delete_cookie('login_token');
发送 Store 中的 Cookie
重要
此方法自 4.1.6 版本起已弃用,并在 4.6.0 版本中移除。
通常无需手动发送 Cookie,CodeIgniter 会自动处理。但若确实需要手动发送,可使用 dispatch 方法。与发送其他标头一样,需先通过 headers_sent() 检查标头是否尚未发送。
<?php
use CodeIgniter\Cookie\Cookie;
use CodeIgniter\Cookie\CookieStore;
$store = new CookieStore([
new Cookie('login_token'),
new Cookie('remember_token'),
]);
$store->dispatch(); // After dispatch, the collection is now empty.
Cookie 个性化设置
Cookie 类内置合理的默认值,确保 Cookie 对象创建顺畅。但可通过修改 app/Config/Cookie.php 文件中的 Config\Cookie 类来定义自定义设置。
设置 |
选项/类型 |
默认值 |
描述 |
|---|---|---|---|
$prefix |
|
|
添加到 Cookie 名称的前缀。 |
$expires |
|
|
过期时间戳。 |
$path |
|
|
Cookie 的路径属性。 |
$domain |
|
|
Cookie 的域名属性(可带尾部斜杠)。 |
$secure |
|
|
是否仅通过 HTTPS 发送。 |
$httponly |
|
|
是否对 JavaScript 不可访问。 |
$samesite |
|
|
SameSite 属性。 |
$raw |
|
|
是否使用 |
运行时可使用 Cookie::setDefaults() 方法手动提供新的默认值。
类参考
- class CodeIgniter\Cookie\Cookie
- static setDefaults([$config = []])
- 参数:
$config (
\Config\Cookie|array) -- 配置数组或实例
- 返回类型:
array- 返回:
旧的默认值
通过注入
Config\Cookie配置或数组的值,为 Cookie 实例设置默认属性。
- static fromHeaderString(string $header[, bool $raw = false])
- 参数:
$header (
string) --Set-Cookie标头字符串$raw (
bool) -- 是否不对 Cookie 进行 URL 编码并通过setrawcookie()发送
- 返回类型:
Cookie- 返回:
Cookie实例- Throws:
CookieException
从
Set-Cookie标头创建新的 Cookie 实例。
- __construct(string $name[, string $value = ''[, array $options = []]])
- 参数:
$name (
string) -- Cookie 名称$value (
string) -- Cookie 值$options (
array) -- Cookie 选项
- 返回类型:
Cookie- 返回:
Cookie实例- Throws:
CookieException
构造新的 Cookie 实例。
- getId()
- 返回类型:
string- 返回:
Cookie 集合中索引使用的 ID。
- getPrefix() → string
- getName() → string
- getPrefixedName() → string
- getValue() → string
- getExpiresTimestamp() → int
- getExpiresString() → string
- isExpired() → bool
- getMaxAge() → int
- getDomain() → string
- getPath() → string
- isSecure() → bool
- isHTTPOnly() → bool
- getSameSite() → string
- isRaw() → bool
- getOptions() → array
- withRaw([bool $raw = true])
- 参数:
$raw (
bool)
- 返回类型:
Cookie- 返回:
新的
Cookie实例
创建带有更新 URL 编码选项的新 Cookie。
- withPrefix([string $prefix = ''])
- 参数:
$prefix (
string)
- 返回类型:
Cookie- 返回:
新的
Cookie实例
创建带有新前缀的新 Cookie。
- withName(string $name)
- 参数:
$name (
string)
- 返回类型:
Cookie- 返回:
新的
Cookie实例
创建带有新名称的新 Cookie。
- withValue(string $value)
- 参数:
$value (
string)
- 返回类型:
Cookie- 返回:
新的
Cookie实例
创建带有新值的新 Cookie。
- withExpires($expires)
- 参数:
$expires (
DateTimeInterface|string|int)
- 返回类型:
Cookie- 返回:
新的
Cookie实例
创建带有新过期时间的新 Cookie。
- withExpired()
- 返回类型:
Cookie- 返回:
新的
Cookie实例
创建将从浏览器中过期的新 Cookie。
- withNeverExpiring()
重要
此方法自 4.2.6 版本起已弃用,并在 4.6.0 版本中移除。
- 参数:
$name (
string)
- 返回类型:
Cookie- 返回:
新的
Cookie实例
创建几乎永不过期的新 Cookie。
- withDomain(?string $domain)
- 参数:
$domain (
string|null)
- 返回类型:
Cookie- 返回:
新的
Cookie实例
创建带有新域名的新 Cookie。
- withPath(?string $path)
- 参数:
$path (
string|null)
- 返回类型:
Cookie- 返回:
新的
Cookie实例
创建带有新路径的新 Cookie。
- withSecure([bool $secure = true])
- 参数:
$secure (
bool)
- 返回类型:
Cookie- 返回:
新的
Cookie实例
创建带有新 "Secure" 属性的新 Cookie。
- withHTTPOnly([bool $httponly = true])
- 参数:
$httponly (
bool)
- 返回类型:
Cookie- 返回:
新的
Cookie实例
创建带有新 "HttpOnly" 属性的新 Cookie。
- withSameSite(string $samesite)
- 参数:
$samesite (
string)
- 返回类型:
Cookie- 返回:
新的
Cookie实例
创建带有新 "SameSite" 属性的新 Cookie。
- toHeaderString()
- 返回类型:
string- 返回:
返回可作为标头字符串传递的字符串表示。
- toArray()
- 返回类型:
array- 返回:
返回 Cookie 实例的数组表示。
- class CodeIgniter\Cookie\CookieStore
- static fromCookieHeaders(array $headers[, bool $raw = false])
- 参数:
$header (
array) --Set-Cookie标头数组$raw (
bool) -- 是否不使用 URL 编码
- 返回类型:
CookieStore- 返回:
CookieStore实例- Throws:
CookieException
从
Set-Cookie标头数组创建 CookieStore。
- __construct(array $cookies)
- 参数:
$cookies (
array) --Cookie对象数组
- 返回类型:
CookieStore- 返回:
CookieStore实例- Throws:
CookieException
- has(string $name[, string $prefix = ''[, ?string $value = null]]) → bool
- 参数:
$name (
string) -- Cookie 名称$prefix (
string) -- Cookie 前缀$value (
string|null) -- Cookie 值
- 返回类型:
bool- 返回:
检查集合中是否存在由名称和前缀标识的
Cookie对象。
- get(string $name[, string $prefix = '']) → Cookie
- 参数:
$name (
string) -- Cookie 名称$prefix (
string) -- Cookie 前缀
- 返回类型:
Cookie- 返回:
按名称和前缀检索 Cookie 实例。
- Throws:
CookieException
- put(Cookie $cookie) → CookieStore
- 参数:
$cookie (
Cookie) -- Cookie 对象
- 返回类型:
CookieStore- 返回:
新的
CookieStore实例
存储新 Cookie 并返回新集合,原集合保持不变。
- remove(string $name[, string $prefix = '']) → CookieStore
- 参数:
$name (
string) -- Cookie 名称$prefix (
string) -- Cookie 前缀
- 返回类型:
CookieStore- 返回:
新的
CookieStore实例
从集合中移除 Cookie 并返回更新后的集合,原集合保持不变。
- dispatch() → void
重要
此方法自 4.1.6 版本起已弃用,并在 4.6.0 版本中移除。
- 返回类型:
void
发送 Store 中的所有 Cookie。
- display() → array
- 返回类型:
array- 返回:
返回 Store 中的所有 Cookie 实例。
- clear() → void
- 返回类型:
void
清空 Cookie 集合。