PHP Cookies
PHP Cookie
Section titled “PHP Cookie”Cookie 是一种在客户端(用户的浏览器)存储少量数据的机制,通常用于在会话之间识别用户或存储偏好设置(preferences)。
什么是 Cookie?
Section titled “什么是 Cookie?”Cookie 是由服务器创建并由用户的 Web 浏览器存储在用户计算机上的一个小文件。当用户从同一服务器请求页面时,浏览器会将相关的 cookie 发送回请求。PHP 提供了创建、检索、修改和删除 cookie 值的功能。
常见的用途包括会话管理(session management)(尽管通常更推荐使用 PHP 的 Session)、个性化(personalization)(例如主题)以及跟踪用户行为(user behavior)(由于隐私问题,现在不太常见)。
使用 PHP 创建 Cookie
Section titled “使用 PHP 创建 Cookie”使用 setcookie() 函数创建 Cookie。调用此函数至关重要,它必须在任何 HTML 输出发送到浏览器之前(在 <html>、<?php echo …; ?> 甚至空白符之前)执行。
语法 (Syntax)
Section titled “语法 (Syntax)”setcookie(name, value, expires_or_options, path, domain, secure, httponly)
或者使用现代的选项数组(PHP 7.3+):
setcookie(name, value, [‘expires’ => expiration_timestamp, ‘path’ => ’/’, ‘domain’ => ‘example.com’, ‘secure’ => true, ‘httponly’ => true, ‘samesite’ => ‘Lax’])
name:Cookie 的名称(必需)。value:要存储的值。会自动进行 URL 编码(URL-encoded)。expires_or_options:(可选)过期时间戳(Unix timestamp)或一个选项数组(推荐)。将过期时间设置为过去的时间会删除该 cookie。path:(可选)cookie 在服务器上的可用路径。’/’ 表示整个域。domain:(可选)cookie 有效的域(例如,对于子域,可以使用 ‘.example.com’)。secure:(可选,布尔值)如果为true,则只通过 HTTPS 连接发送 cookie。强烈推荐。httponly:(可选,布尔值)如果为true,则无法通过客户端脚本(如 JavaScript)访问此 cookie,有助于减轻 XSS 攻击。强烈推荐。samesite:(可选,字符串)控制跨站请求行为(‘None’、‘Lax’、‘Strict’)。有助于减轻 CSRF 攻击。‘Lax’ 通常是一个不错的默认值。
PHP 创建/检索安全 Cookie
Section titled “PHP 创建/检索安全 Cookie”此示例创建一个名为 ‘user’、值为 ‘John Doe’ 的 cookie。它将在 30 天后过期,在整个站点范围内可用,并包含重要的安全标志(security flags)。
然后,我们使用 $_COOKIE 超全局数组(superglobal array)检索该值,并使用 isset() 检查它是否存在。
<?php$cookie_name = "user";$cookie_value = "John Doe";$expiry = time() + (86400 * 30); // 86400 秒 = 1 天$path = "/";$domain = ""; // 当前域$secure = true; // 仅通过 HTTPS 发送$httponly = true; // 阻止 JavaScript 访问
// 使用选项数组的现代语法 (PHP 7.3+)setcookie($cookie_name, $cookie_value, [ 'expires' => $expiry, 'path' => $path, // 'domain' => $domain, // 通常最好留空或明确设置 'secure' => $secure, 'httponly' => $httponly, 'samesite' => 'Lax' // 推荐的默认值]);
/* // Older syntax (still works)setcookie($cookie_name, $cookie_value, $expiry, $path, $domain, $secure, $httponly);*/
?><!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>PHP Cookie Example</title></head><body>
<h1>Cookie Status</h1>
<?phpif (!isset($_COOKIE[$cookie_name])) { echo "Cookie named '" . htmlspecialchars($cookie_name) . "' is not set!";} else { echo "Cookie '" . htmlspecialchars($cookie_name) . "' is set!<br>"; // 始终净化来自 cookie(或任何用户输入)的输出 echo "Value is: " . htmlspecialchars($_COOKIE[$cookie_name]);}?>
<p>**注意:**Cookie 可能不会在设置它们的同一页面加载中立即在 $_COOKIE 中可用。它们由浏览器在后续请求中发送。</p>
</body></html>重要: setcookie() 函数必须在任何输出发送到浏览器之前调用(HTML、空白符、echo/print 语句)。否则,将导致“Headers already sent”警告,并且 cookie 将不会被设置。 |
|---|
注意:cookie 值在发送时会自动进行 URL 编码,并在接收时解码。如果您需要发送未经 URL 编码的值(很少需要),请使用 setrawcookie()。
修改 Cookie 值
Section titled “修改 Cookie 值”要修改 cookie,只需使用相同的名称、新的值和/或过期时间再次调用 setcookie()。请确保使用与原始 cookie 相同的路径(path)、域(domain)、secure 和 httponly 设置。
<?php$cookie_name = "user";$new_value = "Alex Porter";$expiry = time() + (86400 * 30);$path = "/";$secure = true;$httponly = true;
// Set the cookie again with the new valuesetcookie($cookie_name, $new_value, [ 'expires' => $expiry, 'path' => $path, 'secure' => $secure, 'httponly' => $httponly, 'samesite' => 'Lax']);?><!DOCTYPE html><html lang="en"><head><title>Modify Cookie</title></head><body><h1>Modifying Cookie</h1><p>Cookie '<?php echo htmlspecialchars($cookie_name); ?>' value is being updated.</p><?phpif (isset($_COOKIE[$cookie_name])) { echo "<p>Current value (from previous request): " . htmlspecialchars($_COOKIE[$cookie_name]) . "</p>";} echo "<p>New value set to: " . htmlspecialchars($new_value) . " (will be visible on next page load)</p>";?></body></html>删除 Cookie
Section titled “删除 Cookie”要删除 cookie,请使用 cookie 的名称和过去的过期日期调用 setcookie()。同样,为了使删除操作正确生效,需要匹配 path、domain 等设置。
<?php$cookie_name = "user";
// 将过期日期设置为一小时前setcookie($cookie_name, "", time() - 3600, "/", "", true, true); // 匹配 path, secure, httponly
// 或者,使用选项数组:/*setcookie($cookie_name, '', [ 'expires' => time() - 3600, 'path' => '/', 'secure' => true, 'httponly' => true, 'samesite' => 'Lax']);*/?><!DOCTYPE html><html lang="en"><head><title>Delete Cookie</title></head><body><h1>Deleting Cookie</h1><p>Cookie '<?php echo htmlspecialchars($cookie_name); ?>' has been deleted (or attempted deletion).</p><?php// 在当前脚本中取消设置变量以立即生效(但这不会删除浏览器中的 cookie)unset($_COOKIE[$cookie_name]);
if (!isset($_COOKIE[$cookie_name])) { echo "<p>Cookie variable is now unset in this script execution.</p>";} else { echo "<p>Cookie variable still exists in this script execution (unexpected).</p>";}?><p>刷新页面以确认浏览器不再发送该 cookie。</p></body></html>检查 Cookie 是否启用
Section titled “检查 Cookie 是否启用”您可以通过尝试设置一个测试 cookie,然后在后续请求中检查它是否存在来检查 cookie 是否启用。一种常见的技术是设置一个 cookie,然后立即重定向或提供一个链接到另一个页面,该页面检查是否存在该 cookie。
简单检查(不太可靠,可能会显示先前访问时留下的 cookie):
<?php// 尝试设置一个测试 cookiesetcookie("test_cookie", "test_value", time() + 3600, '/', '', true, true);?><!DOCTYPE html><html lang="en"><head><title>Check Cookies Enabled</title></head><body><h1>Checking Cookie Support</h1><?php// 检查 $_COOKIE 是否有内容。这是一个基本检查。// 更可靠的检查方法是设置一个 cookie,然后在 *下一个* 页面加载时检查它是否存在。if (count($_COOKIE) > 0) { echo "<p>Cookie 似乎已启用(找到现有或测试 cookie)。</p>";} else { // 如果这是第一次访问并且测试 cookie 尚未注册,可能会触发此情况。 echo "<p>Cookie 可能被禁用,或者这是第一次访问。</p>";}?><p><a href="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>">刷新页面</a>以查看是否检测到测试 cookie。</p></body></html>对于管理用户会话(user sessions)或更复杂的数据持久化(data persistence),通常推荐使用 PHP Session($_SESSION),而不是直接使用原始 cookie。Session 通常在内部使用 cookie,但以更安全、更抽象的方式处理存储和检索。对于无状态认证(stateless authentication),存储在 cookie 或本地存储(local storage)中的 JSON Web Token (JWT) 也非常流行。