PHP项目Cookie如何创建读取删除

wen PHP项目 20

PHP项目Cookie操作全指南:创建、读取与删除的完整实践

目录导读

  1. Cookie基础与HTTP协议原理
  2. PHP中Cookie的创建方法详解
  3. Cookie读取的三种常见场景
  4. Cookie删除的正确姿势与陷阱
  5. 安全最佳实践:HttpOnly、Secure与SameSite
  6. 实战问答(Q&A)
  7. 总结与代码仓库

Cookie基础与HTTP协议原理

在开始PHP编码之前,理解Cookie在HTTP协议中的定位至关重要,Cookie是服务器通知客户端(浏览器)存储少量数据的一种机制,每次请求时浏览器会将该数据附带到请求头中,PHP通过$_COOKIE超全局数组读取,通过setcookie()函数写入或删除。

PHP项目Cookie如何创建读取删除

注意:Cookie存储在客户端,大小限制通常为4KB,且每个域名下数量有限(一般50个左右),敏感数据切勿明文存储,建议配合加密或使用Session。


PHP中Cookie的创建方法详解

1 基础语法

setcookie(string $name, string $value = "", int $expires_or_options = 0, 
         string $path = "", string $domain = "", bool $secure = false, 
         bool $httponly = false): bool

2 创建持久Cookie(指定过期时间)

// 有效期为1小时
setcookie('user_token', 'abc123', time() + 3600, '/');
  • time() + 3600:当前时间加3600秒
  • 路径,表示整个网站有效

3 创建会话Cookie(关闭浏览器失效)

setcookie('session_id', 'temp_value', 0);
// 第3个参数为0或省略,浏览器关闭后自动删除

4 创建安全Cookie(仅HTTPS传输)

setcookie('secure_cookie', 'value', 0, '/', '', true, false);
// secure=true 表示仅通过HTTPS发送

5 创建HttpOnly Cookie(防止XSS窃取)

setcookie('admin_role', 'editor', 0, '/', '', false, true);
// httponly=true 后,JavaScript无法读取该Cookie

关键注意事项

  • Cookie必须在任何HTML输出之前调用(包括空格、BOM头)
  • 如果使用setrawcookie(),不会自动URL编码,需手动处理特殊字符

Cookie读取的三种常见场景

1 直接读取当前请求中的Cookie

if (isset($_COOKIE['user_token'])) {
    $token = $_COOKIE['user_token'];
    echo "当前用户Token: " . htmlspecialchars($token);
} else {
    echo "Cookie不存在或已过期";
}

2 读取所有Cookie

// 遍历$_COOKIE数组
foreach ($_COOKIE as $key => $value) {
    echo "$key : " . htmlspecialchars($value) . "<br>";
}

3 从Cookie获取数组数据

// 设置时存储JSON
setcookie('user_prefs', json_encode(['theme' => 'dark', 'lang' => 'zh']), time()+86400, '/');
// 读取时解码
if (isset($_COOKIE['user_prefs'])) {
    $prefs = json_decode($_COOKIE['user_prefs'], true);
    echo "用户主题: " . $prefs['theme'];
}

注意陷阱

  • $_COOKIE 是当前请求接收到的Cookie,新设置的setcookie()不会立即出现在$_COOKIE中,需在下一次请求中才能读取
  • 读取前必须检查isset(),避免未定义索引报错

Cookie删除的正确姿势与陷阱

1 标准删除方法(设置过去时间)

// 将过期时间设置为1小时前
setcookie('user_token', '', time() - 3600);

这是最常用且最可靠的方式,原理:浏览器发现Cookie已过期,自动清除。

2 完全清除(指定与创建时相同的路径和域名)

// 假设创建时使用setcookie('cart', 'item1', 0, '/shop', '.example.com');
// 删除时必须完全匹配
setcookie('cart', '', time() - 3600, '/shop', '.example.com');

如果不匹配路径或域名,删除操作可能无效,浏览器仍会保留该Cookie。

3 批量删除所有Cookie

if (isset($_SERVER['HTTP_COOKIE'])) {
    $cookies = explode(';', $_SERVER['HTTP_COOKIE']);
    foreach ($cookies as $cookie) {
        $parts = explode('=', $cookie);
        $name = trim($parts[0]);
        setcookie($name, '', time() - 3600, '/');
    }
}

常见错误行为

  • 直接设值为空字符串setcookie('name', ''); 只会清理值,不会删除Cookie本身,浏览器仍会保留该Cookie(无值)
  • 忽略路径:若Cookie在 /admin 路径下创建,在根路径 删除会失败

安全最佳实践:HttpOnly、Secure与SameSite

1 HttpOnly(防XSS读取)

setcookie('private_data', 'sensitive', 0, '/', '', true, true);
// 第7个参数为true

即使网页存在XSS漏洞,攻击者通过document.cookie也无法获取该Cookie。

2 Secure(防中间人攻击)

setcookie('payment_token', 'abc', 0, '/', '', true);
// secure=true 仅HTTPS传输

3 SameSite(防CSRF攻击)

PHP 7.3+ 支持通过options数组设置:

setcookie('csrf_token', 'random123', [
    'expires' => time() + 3600,
    'path' => '/',
    'domain' => '.example.com',
    'secure' => true,
    'httponly' => true,
    'samesite' => 'Lax'  // 或 'Strict' / 'None'
]);
  • Strict:完全禁用跨站发送,但影响用户体验
  • Lax:允许GET请求(如链接、预加载)发送,推荐用于大多数场景
  • None:需配合Secure=true,允许所有跨站请求

4 加密存储敏感数据

// 加密存储
$encryptedValue = openssl_encrypt('user_email@example.com', 'AES-256-CBC', $key, 0, $iv);
setcookie('email', base64_encode($encryptedValue), 0, '/', '', true, true);
// 读取解密
$decoded = base64_decode($_COOKIE['email']);
$original = openssl_decrypt($decoded, 'AES-256-CBC', $key, 0, $iv);

实战问答(Q&A)

Q1: 为什么我设置Cookie后,$_COOKIE 里没有立即出现?
A: 因为$_COOKIE反映的是浏览器发来的请求头,setcookie()仅发送响应头给浏览器,新Cookie需要浏览器下一次请求时才会返回,若需立即使用,可手动赋值:$_COOKIE['name'] = 'value';

Q2: setcookie()返回false,排查思路是什么?
A: 检查三项:① 是否有任何HTML输出(包括空格)在setcookie()之前;② 是否开启了输出缓冲区(ob_start()可临时解决);③ 插误是否被PHP错误抑制(符号)。

Q3: 如何解决Cookie被浏览器拒绝的问题?
A: 检查浏览器隐私设置,有无第三方Cookie限制(尤其是SameSite=None时),开发者可通过setcookie()返回的falseerror_get_last()获取错误原因。

Q4: 删除Cookie时,域名和路径必须和创建时完全一致吗?
A: 路径必须一致(或包含被删除Cookie的路径),域名可以省略,但通常保持一致更安全,如果省略域名,默认使用当前域名。


总结与代码仓库

Cookie是PHP开发中不可或缺的状态管理工具,但易因细节疏忽导致问题,核心原则:

  • 创建:在输出任何内容前调用,指定路径和过期时间
  • 读取:必须检查isset(),注意新Cookie不能立即读取
  • 删除:使用负过期时间+完全匹配路径/域名
  • 安全:强制使用HttpOnly、Secure、SameSite三道防线

完整示例代码片段(包含所有操作):

// 创建
setcookie('lang', 'zh-CN', time() + 86400*30, '/', '', true, true);
// 读取
$lang = isset($_COOKIE['lang']) ? $_COOKIE['lang'] : 'en';
// 删除
setcookie('lang', '', time() - 3600, '/', '', true, true);

项目实践建议:在大型项目中,推荐封装Cookie管理类,统一处理路径、加密、过期逻辑,避免散落各处的setcookie()调用造成维护困难。

抱歉,评论功能暂时关闭!