首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 批量刪除 Cookie 完整指南:單個/多個/模式匹配/域路徑控制與安全清理

     編輯:PHP 綜合知識

核心原理

刪除 Cookie 本質是設置一個已過期的 Cookie,瀏覽器收到後會刪除本地存儲。關鍵參數:

  • 名稱:要刪除的 Cookie 名
  • 值:任意(通常空字符串)
  • 過期時間:過去時間戳(如 time() - 3600)
  • 路徑:必須與設置時完全一致(含域、路徑、安全屬性)

基礎刪除方法

<?php
// 刪除單個 Cookie
setcookie('username', '', time() - 3600, '/'); // 路徑必須匹配

// 刪除多個 Cookie(遍歷 $_COOKIE)
foreach ($_COOKIE as $name => $value) {
    setcookie($name, '', time() - 3600, '/');
}

// 刪除指定前綴的 Cookie
$prefix = 'app_';
foreach ($_COOKIE as $name => $value) {
    if (str_starts_with($name, $prefix)) {
        setcookie($name, '', time() - 3600, '/');
    }
}
?>

完整封裝類:支援模式匹配、域路徑控制、批量操作

class CookieManager {
    private string $defaultPath = '/';
    private string $defaultDomain = '';
    private bool $secure;
    private bool $httponly = true;
    private string $samesite = 'Lax';
    
    public function __construct(array $options = []) {
        $this->defaultPath = $options['path'] ?? '/';
        $this->defaultDomain = $options['domain'] ?? '';
        $this->secure = $options['secure'] ?? isset($_SERVER['HTTPS']);
    }
    
    /**
     * 設置 Cookie
     */
    public function set(string $name, string $value, int $expire = 0, array $options = []): bool {
        $opts = array_merge([
            'expires'  => $expire ?: time() + 86400 * 30,
            'path'     => $this->defaultPath,
            'domain'   => $this->defaultDomain,
            'secure'   => $this->secure,
            'httponly' => $this->httponly,
            'samesite' => $this->samesite,
        ], $options);
        
        return setcookie($name, $value, $opts);
    }
    
    /**
     * 刪除單個 Cookie
     */
    public function delete(string $name, array $options = []): bool {
        $opts = array_merge([
            'expires' => time() - 3600,
            'path'    => $this->defaultPath,
            'domain'  => $this->defaultDomain,
            'secure'  => $this->secure,
            'httponly'=> $this->httponly,
            'samesite'=> $this->samesite,
        ], $options);
        
        return setcookie($name, '', $opts);
    }
    
    /**
     * 批量刪除:支援精確名單、前綴、正則、回調函數
     */
    public function deleteBatch(array|string|callable $matcher, array $options = []): int {
        $deleted = 0;
        
        foreach ($_COOKIE as $name => $value) {
            $shouldDelete = match (true) {
                is_array($matcher)     => in_array($name, $matcher, true),
                is_string($matcher)    => $name === $matcher || str_starts_with($name, $matcher),
                is_callable($matcher)  => $matcher($name, $value),
                default                => false,
            };
            
            if ($shouldDelete) {
                if ($this->delete($name, $options)) $deleted++;
            }
        }
        
        return $deleted;
    }
    
    /**
     * 清空當前域下所有 Cookie(謹慎使用)
     */
    public function clearAll(array $options = []): int {
        return $this->deleteBatch(fn($name) => true, $options);
    }
    
    /**
     * 獲取 Cookie(帶默認值、類型轉換)
     */
    public function get(string $name, $default = null, callable $caster = null) {
        if (!isset($_COOKIE[$name])) return $default;
        $value = $_COOKIE[$name];
        return $caster ? $caster($value) : $value;
    }
    
    /**
     * 檢查 Cookie 是否存在
     */
    public function has(string $name): bool {
        return isset($_COOKIE[$name]);
    }
}

// 使用示例
$cookie = new CookieManager(['path' => '/', 'secure' => true]);

// 設置
$cookie->set('user_id', '12345', time() + 3600);
$cookie->set('theme', 'dark', time() + 86400 * 30);
$cookie->set('app_token', 'abc123', time() + 3600);
$cookie->set('app_refresh', 'xyz789', time() + 86400 * 7);

// 刪除單個
$cookie->delete('user_id');

// 刪除前綴匹配
$cookie->deleteBatch('app_'); // 刪除 app_token, app_refresh

// 刪除正則匹配(PHP 8+)
$cookie->deleteBatch(fn($name) => preg_match('/^temp_/', $name));

// 刪除精確名單
$cookie->deleteBatch(['theme', 'lang']);

// 清空所有
$cookie->clearAll();

關鍵坑點:路徑與域必須精確匹配

// ❌ 錯誤:設置時 path=/admin,刪除時 path=/
setcookie('admin_pref', 'value', time()+3600, '/admin');
// 後續...
setcookie('admin_pref', '', time()-3600, '/'); // 無效!路徑不匹配

// ✅ 正確:刪除時使用相同路徑
setcookie('admin_pref', '', time()-3600, '/admin');

// ✅ 最佳實踐:封裝類統一管理路徑/域
$cookie = new CookieManager(['path' => '/admin']);
$cookie->set('pref', 'value');
$cookie->delete('pref'); // 內部自動使用正確路徑

安全清理場景

場景清理策略代碼示例
用戶登出刪除認證相關 Cookie,保留偏好設置$cookie->deleteBatch(['token', 'user_id', 'remember_me']);
權限變更刪除權限緩存 Cookie,強制重新獲取$cookie->deleteBatch(fn($n) => str_starts_with($n, 'perm_'));
隱私合規(GDPR)用戶請求刪除所有追蹤 Cookie$cookie->deleteBatch(fn($n) => !in_array($n, ['necessary_cookie']));
會話劫持應急全站強制刷新所有用戶 Cookie修改 Cookie 名稱前綴或密鑰,舊 Cookie 自動失效
測試/調試開發者工具一鍵清理瀏覽器 DevTools → Application → Cookies → 右鍵清除

JavaScript 協同清理(前端配合)

// 前端 JS 刪除 Cookie(需同域、同路徑)
function deleteCookie(name, path = '/', domain = '') {
    document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=${path}${domain ? '; domain=' + domain : ''}; SameSite=Lax`;
}

// 批量刪除
function deleteCookiesByPrefix(prefix) {
    document.cookie.split(';').forEach(c => {
        const name = c.split('=')[0].trim();
        if (name.startsWith(prefix)) deleteCookie(name);
    });
}

// 登出時調用
deleteCookie('token');
deleteCookie('user_id');
deleteCookiesByPrefix('app_');

調試技巧

// 查看即將發送的 Set-Cookie 頭(不實際發送)
function debugSetCookie(string $name, string $value, array $options = []) {
    $opts = array_merge([
        'expires'  => time() + 3600,
        'path'     => '/',
        'domain'   => '',
        'secure'   => false,
        'httponly' => true,
        'samesite' => 'Lax',
    ], $options);
    
    $parts = [$name . '=' . urlencode($value)];
    $parts[] = 'Expires=' . gmdate('D, d-M-Y H:i:s T', $opts['expires']);
    $parts[] = 'Path=' . $opts['path'];
    if ($opts['domain']) $parts[] = 'Domain=' . $opts['domain'];
    if ($opts['secure']) $parts[] = 'Secure';
    if ($opts['httponly']) $parts[] = 'HttpOnly';
    $parts[] = 'SameSite=' . $opts['samesite'];
    
    return 'Set-Cookie: ' . implode('; ', $parts);
}

// 測試
echo debugSetCookie('test', 'value', ['path' => '/admin']);
// 輸出: Set-Cookie: test=value; Expires=...; Path=/admin; HttpOnly; SameSite=Lax

總結

PHP 批量刪除 Cookie 核心在於精確匹配設置時的路徑、域、安全屬性。封裝 CookieManager 類統一管理配置,支援精確名單、前綴匹配、正則、回調函數多種批量模式,配合前端 JS 協同清理,可覆蓋登出、權限變更、隱私合規、應急響應等全場景。關鍵原則:設置與刪除參數完全一致、封裝統一管理、最小權限、安全屬性全開、操作可審計。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved