この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:4
ページ更新者:guest
更新日時:2026-06-11 07:07:02

タイトル: $_COOKIE
SEOタイトル: PHP $_COOKIE スーパーグローバル変数完全ガイド(setcookie / Secure / HttpOnly / SameSite)

この記事の要点
  • $_COOKIE はクライアントから送られてきた Cookie を格納するスーパーグローバル配列
  • 書き込みは setcookie()。第7引数までで expires / path / domain / secure / httponly / samesite を指定
  • Secure / HttpOnly / SameSite はセキュリティ必須。XSS / CSRF 緩和のため原則全てを有効化
  • Cookie 削除は有効期限を過去にした setcookie() を再送信
  • サイズ制限は1 Cookie 約 4KB / 1 ドメイン 50 個程度。機密データは Session に

$_COOKIE とは

$_COOKIE は PHP のスーパーグローバル変数の一つで、HTTP リクエストヘッダの Cookie: でクライアントから送られてきた値が、名前 => 値の連想配列として格納されています。

PHP $_COOKIE の概要

 string(26) "abc123..."
//   ["lang"]=>     string(2)  "ja"
// }

// 個別取得
$lang = $_COOKIE['lang'] ?? 'en';

// 存在チェック
if (isset($_COOKIE['user_id'])) {
    echo "ようこそ ID:" . htmlspecialchars($_COOKIE['user_id']);
}

注意点として、$_COOKIEクライアントが提示した値であり、ユーザーが書き換え可能です。サーバ側ロジックの認可判定に使う場合、必ず署名 / Session ID / トークンで改ざん検知を行ってください。

setcookie() で Cookie を書き込む

setcookie() の引数とブラウザ確認

PHP 7.3 以降では連想配列で指定する形式が推奨されています:

 time() + 3600,        // 1時間後
    'path'     => '/',
    'domain'   => 'example.com',
    'secure'   => true,                 // HTTPS のみ送信
    'httponly' => true,                 // JavaScript 不可
    'samesite' => 'Lax',                // CSRF 対策 (Lax / Strict / None)
]);

// 旧形式(PHP 7.2 以前との互換)
setcookie('lang', 'ja', time() + 86400, '/', '', true, true);
//                ↑          ↑    ↑          ↑  ↑      ↑    ↑
//                value     expires path domain secure httponly

setcookie()HTTP ヘッダで送出するため、必ず echo や HTML 出力よりに呼び出します。出力後に呼ぶと Cannot modify header information - headers already sent エラーになります。

セキュリティ属性: Secure / HttpOnly / SameSite

属性効果推奨
SecureHTTPS 接続でのみ Cookie を送信常に true(HTTPS 環境前提)
HttpOnlyJavaScript (document.cookie) から不可視セッション系は必ず true(XSS 軽減)
SameSite=Strict同サイト発リクエストのみ送信強固。OAuth リダイレクトで切れる
SameSite=Lax同サイト + トップレベルナビゲーション GET★ 既定の現実解
SameSite=Noneクロスサイト送信を許可(要 Secure)埋め込み iframe など限定

Chrome DevTools での Cookie 属性確認

Cookie の削除

Cookie 専用の削除 API はありません。有効期限を過去に設定した同名 Cookie を送ると、ブラウザが削除します。

 time() - 3600,   // 過去
    'path'     => '/',
    'domain'   => 'example.com',
    'secure'   => true,
    'httponly' => true,
    'samesite' => 'Lax',
]);

// 削除時の path / domain は 設定時と同じでないと削除されない
// 設定: path=/admin で書いた Cookie は path=/admin で削除する

Cookie 読み取りの実例

PHP コードで $_COOKIE を読み取る例

 time() + 86400 * 30,
    'path'     => '/',
    'secure'   => true,
    'httponly' => true,
    'samesite' => 'Lax',
]);

// 認証トークンの検証(HMAC 署名例)
$token   = $_COOKIE['auth'] ?? '';
[$payload, $sig] = explode('.', $token, 2) + ['', ''];
$expect  = hash_hmac('sha256', $payload, $secretKey);
if (hash_equals($expect, $sig)) {
    // 改ざんなし
    $user = json_decode(base64_decode($payload), true);
}

Cookie の制限

項目制限
1 Cookie のサイズ約 4KB(4096 バイト)
1 ドメインあたりの Cookie 数約 50 個(ブラウザ依存、Chrome は約 180)
1 ドメインの Cookie 合計サイズ約 4KB × 個数
名前に使える文字RFC 6265 トークン、= , ; 不可
値に使える文字制御文字 / , ; " 不可(PHP は自動で URL エンコード)

Cookie vs Session の使い分け

用途CookieSession
言語・テーマ設定
同意バナー記録
ログイン状態セッション ID のみ★(ユーザー情報本体)
カート内容軽量なら可★ 重い場合
パスワード / トークン秘密×

セッションハイジャック対策

  • HTTPS 強制(HSTS)+ Secure 属性
  • HttpOnlyXSS 経由の盗難を防ぐ
  • SameSite=Lax 以上で CSRF を緩和
  • ログイン直後に session_regenerate_id(true)セッション固定攻撃防止
  • 長時間使うトークンは定期ローテーション(refresh token 方式)
  • 機密 Cookie は __Host- プレフィックス(Secure + path=/ + domain なし強制)

Content Security Policy (CSP) との連携

# レスポンスヘッダ
Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: strict-origin-when-cross-origin

CSP で XSS の発生確率を下げ、HttpOnly Cookie の漏洩リスクを併せて低減できます。

Laravel の Cookie ファサード

use Illuminate\Support\Facades\Cookie;

// 書き込み(暗号化 + 署名済み)
return response('OK')->cookie(
    'lang', 'ja', 60, '/', null, true, true, false, 'Lax'
);

// 読み取り
$lang = request()->cookie('lang', 'en');

// 削除
return response('OK')->withCookie(Cookie::forget('lang'));

// 暗号化を除外(フロント JS で読みたい場合)
// app/Http/Middleware/EncryptCookies.php
protected $except = ['lang'];

Laravel は既定でCookie を AES 暗号化するため、生 PHP の $_COOKIE から直接読むと暗号文が返ります。フロント側で読みたい Cookie は EncryptCookies の除外リストに入れます。

FAQ

Q: setcookie() したのに $_COOKIE に出ない
A: $_COOKIE次のリクエストから反映されます。同じリクエスト内で参照したい場合は $_COOKIE['x'] = 'v' も手で設定するか、setcookie() 直後にローカル変数で持ちます。

Q: ヘッダ送信済みエラーが出る
A: ファイル先頭の BOM / 余計な空白、もしくは echo 後に setcookie() を呼んでいます。ob_start() でバッファリングするか、出力前に呼びましょう。

Q: SameSite=None にしたら Cookie が送られなくなった
A: モダンブラウザは SameSite=None 時に Secure を要求します。HTTPS 環境で Secure=true を併用してください。