Cookie
HTTP Cookie(网页 Cookie,浏览器 Cookie)是服务器发送给用户网页浏览器的少量数据。浏览器可以存储它并在以后向同一服务器发送请求时将其发送回去。通常,它用于判断两个请求是否来自同一个浏览器 - 例如,保持用户登录状态。它为无状态的 HTTP 协议记住有状态信息。
Cookie 主要用于三个目的
会话管理:登录、购物车、游戏得分或服务器应记住的任何其他内容
个性化:用户偏好、主题和其他设置
跟踪:记录和分析用户行为
为了帮助您有效地将 Cookie 发送到浏览器,CodeIgniter 提供了 CodeIgniter\Cookie\Cookie
类来抽象 Cookie 交互。
创建 Cookie
目前有四 (4) 种方法可以创建一个新的 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
类中保存的默认值填充。
覆盖默认值
要覆盖当前存储在类中的默认值,可以将 Config\Cookie
实例或默认值数组传递给静态 Cookie::setDefaults()
方法。
<?php
use CodeIgniter\Cookie\Cookie;
use Config\Cookie as CookieConfig;
// pass in a Config\Cookie instance before constructing a Cookie class
Cookie::setDefaults(new CookieConfig());
$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');
将 Config\Cookie
实例或数组传递给 Cookie::setDefaults()
将有效地覆盖您的默认值,并将持续存在,直到传递新的默认值。
更改默认值以限制时间
如果您不希望这种行为,而只想在有限的时间内更改默认值,则可以利用 Cookie::setDefaults()
返回值,该返回值返回旧的默认值数组。
<?php
use CodeIgniter\Cookie\Cookie;
use Config\Cookie as CookieConfig;
$oldDefaults = Cookie::setDefaults(new CookieConfig());
$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
。
验证名称属性
cookie 名称可以是任何 US-ASCII 字符,但以下字符除外
控制字符;
空格或制表符;
分隔符,例如
( ) < > @ , ; : \ " / [ ] ? = { }
如果将 $raw
参数设置为 true
,则将严格执行此验证。这是因为 PHP 的 setcookie() 和 setrawcookie() 将拒绝具有无效名称的 cookie。此外,cookie 名称不能是空字符串。
验证前缀属性
使用 __Secure-
前缀时,必须将 $secure
标志设置为 true
来设置 cookie。如果使用 __Host-
前缀,cookie 必须具有以下特征
$secure
标志设置为true
$domain
为空$path
必须为/
验证 SameSite 属性
SameSite 属性仅接受三个 (3) 值
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
在响应对象的 CookieStore
中设置 Cookie
对象,框架将自动发送 cookie。
使用 CodeIgniter\HTTP\Response::setCookie()
设置
<?php
use CodeIgniter\Cookie\Cookie;
use Config\Services;
$response = Services::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 存储
注意
通常,不需要直接使用 CookieStore。
CookieStore
类表示一个不可变的 Cookie
对象集合。
从响应中获取存储
可以从当前的 Response
对象访问 CookieStore
实例。
<?php
use Config\Services;
$cookieStore = Services::response()->getCookieStore();
创建 CookieStore
CodeIgniter 提供了三种 (3) 其他方法来创建 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
数组。
检查存储中的 Cookie
要检查 CookieStore
实例中是否存在 Cookie
对象,可以使用多种方法
<?php
use CodeIgniter\Cookie\Cookie;
use CodeIgniter\Cookie\CookieStore;
use Config\Services;
// 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');
Services::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');
获取存储中的 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');
Services::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 时没有提供任何参数,则将显示存储中的所有 Cookie
对象。
<?php
use Config\Services;
cookies()->get(); // array of Cookie objects
// alternatively, you can use the display method
cookies()->display();
// or even from the Response
Services::response()->getCookies();
注意
辅助函数 get_cookie()
从当前 Request
对象获取 cookie,而不是从 Response
获取。此函数检查 $_COOKIE
数组,如果该 cookie 已设置,则立即获取它。
在存储中添加/删除 Cookie
如前所述,CookieStore
对象是不可变的。您需要保存修改后的实例才能对其进行操作。原始实例保持不变。
<?php
use CodeIgniter\Cookie\Cookie;
use CodeIgniter\Cookie\CookieStore;
use Config\Services;
$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');
注意
从存储中删除 cookie **不会** 从浏览器中删除它。如果您打算从浏览器中删除 cookie,则必须将具有相同名称的空值 cookie 放入存储中。
在当前 Response
对象的存储中与 cookie 交互时,您可以安全地添加或删除 cookie,而无需担心 cookie 集合的不可变性。 Response
对象将用修改后的实例替换该实例。
<?php
use Config\Services;
Services::response()->setCookie('admin_token', 'yes');
Services::response()->deleteCookie('login_token');
// using the cookie helper
helper('cookie');
set_cookie('admin_token', 'yes');
delete_cookie('login_token');
调度存储中的 Cookie
自版本 4.1.6 起已弃用。
重要
此方法已弃用。它将在将来的版本中删除。
大多数情况下,您不需要手动发送 cookie。CodeIgniter 会为您完成此操作。但是,如果您确实需要手动发送 cookie,可以使用 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
) – 是否不进行 URL 编码并通过setrawcookie()
发送此 cookie
- 返回类型:
Cookie
- 返回值:
Cookie
实例- 抛出:
CookieException
从
Set-Cookie
标头创建一个新的 Cookie 实例。
- __construct(string $name[, string $value = ''[, array $options = []]])
- 参数:
$name (
string
) – Cookie 名称$value (
string
) – Cookie 值$options (
array
) – Cookie 选项
- 返回类型:
Cookie
- 返回值:
Cookie
实例- 抛出:
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
实例
创建一个新的 Cookie,并更新 URL 编码选项。
- 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 过期时间的新 Cookie。
- withExpired()
- 返回类型:
Cookie
- 返回值:
新的
Cookie
实例
创建一个将在浏览器中过期的 Cookie。
- withNeverExpiring()
自版本 4.2.6 起已弃用。
重要
此方法已弃用。它将在将来的版本中删除。
- 参数:
$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
实例- 抛出:
CookieException
从
Set-Cookie
头部的数组创建 CookieStore。
- __construct(array $cookies)
- 参数:
$cookies (
array
) –Cookie
对象的数组
- 返回类型:
CookieStore
- 返回值:
CookieStore
实例- 抛出:
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 实例。
- 抛出:
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
- 返回类型:
void
分发存储中的所有 Cookie。
- display() → array
- 返回类型:
array
- 返回值:
返回存储中的所有 Cookie 实例。
- clear() → void
- 返回类型:
void
清除 Cookie 集合。