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

PHP Cookie 實現二級域名共享:domain 參數設定、跨子域名存取與安全屬性完整指南

     編輯:PHP 綜合知識

主域名 example.com 設定 Cookie,需讓 a.example.com、b.example.com 等所有子域名可讀取。關鍵在於 setcookie() 第 5 參數 domain 設為 .example.com (前置點號) 或 example.com。本文詳細解析三種寫法差異、瀏覽器相容性、安全屬性 (Secure、HttpOnly、SameSite)、跨域 Session 共享方案與封裝類別。

三種 domain 設定對比

寫法Cookie Domain可讀取域名標準合規備註
setcookie('k','v',...,'/','*.example.com')*.example.com❌ 失效❌ 非標準通配符星號不被支援
setcookie('k','v',...,'/','.example.com').example.com✅ example.com + *.example.com✅ RFC 2109/6265推薦,前置點號明確表示包含子域
setcookie('k','v',...,'/','example.com')example.com✅ example.com + *.example.com✅ RFC 6265現代瀏覽器同樣支援子域,但舊版 IE 可能有問題

完整安全設定範例

 $expire,
    'path'     => '/',              // 全站可用
    'domain'   => '.' . $domain,    // 關鍵:前置點號共享子域
    'secure'   => true,             // 僅 HTTPS 傳輸 (生產必開)
    'httponly' => true,             // JS 無法讀取 (防 XSS 竊取)
    'samesite' => 'Lax',            // CSRF 防護: Lax/Strict/None
]);

Cookie 封裝類 (支援陣列值、自動序列化、加密可擴展)

name = $name;
        $this->expire = $expire ?: time() + 3600 * 24 * 30;
        $this->path = $path;
        $this->domain = $domain ? ('.' . ltrim($domain, '.')) : '';
        $this->secure = $secure;
        $this->httponly = $httponly;
        $this->samesite = $samesite;
        $this->load();
    }

    private function load(): void {
        if (isset($_COOKIE[$this->name])) {
            $val = $_COOKIE[$this->name];
            if (get_magic_quotes_gpc()) $val = stripslashes($val);
            $this->data = @unserialize($val) ?: [];
        }
    }

    public function get(string $key, $default = null) {
        return $this->data[$key] ?? $default;
    }

    public function set(string $key, $value): void {
        $this->data[$key] = $value;
    }

    public function delete(string $key): void {
        unset($this->data[$key]);
    }

    public function clear(): void {
        $this->data = [];
    }

    public function save(): void {
        $val = serialize($this->data);
        if (strlen($val) > 4000) {
            trigger_error("Cookie {$this->name} exceeds 4KB limit", E_USER_WARNING);
        }
        setcookie($this->name, $val, [
            'expires' => $this->expire,
            'path' => $this->path,
            'domain' => $this->domain,
            'secure' => $this->secure,
            'httponly' => $this->httponly,
            'samesite' => $this->samesite,
        ]);
    }
}

// 使用
$cookie = new CookieManager('app_data', 0, '/', 'example.com');
$cookie->set('user_id', 12345);
$cookie->set('prefs', ['theme'=>'dark','lang'=>'zh_TW']);
$cookie->save();

// 讀取
$userId = $cookie->get('user_id');
$prefs = $cookie->get('prefs', []);

跨子域名 Session 共享 (比 Cookie 更適合敏感資料)



常見問題排查

🔧 避坑指南
  • 開發環境 localhost:無法設定 .localhost。解決:修改 /etc/hosts 加入 127.0.0.1 dev.example.com,用 dev.example.com 訪問。
  • Secure=true 但本地無 HTTPS:Cookie 不會被瀏覽器儲存。開發環境暫設 secure=false 或用 mkcert 簽本地憑證。
  • SameSite=None 需 Secure=true:跨站請求需攜帶 Cookie 時設 samesite='None', secure=true。
  • 4KB 大小限制:單 Cookie 不超 4KB,總數每域 ~150-300 個。大量資料請用 Session/資料庫/本地儲存。
  • 子域名無法讀取:檢查 domain 參數是否含前置點、path 是否為 /、是否同一主域名 (公共後綴列表影響,如 github.io 不共享)。

正確設定 domain=.example.com 配合 Secure、HttpOnly、SameSite,是實現跨子域名認證共享的基石。敏感資料 (用戶 ID、權限) 優先用 Session + session.cookie_domain,非敏感偏好設定可用 Cookie。

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