`setcookie()` と `$_COOKIE`
テクノロジ系 / session-cookie (session / cookie / login / CSRF)
setcookie() と $_COOKIE
Lesson 13 / Chapter 3
Cookie のやり取り (絵)
1. ブラウザがリクエスト GET / HTTP/1.1 2. サーバーがレスポンスに Set-Cookie ヘッダを乗せる HTTP/1.1 200 OK Set-Cookie: name=taro 3. ブラウザが Cookie を保存する 4. 次回以降のリクエストに自動で乗せて送る GET /page HTTP/1.1 Cookie: name=taro
PHP からは:
- 書き出す:
setcookie('name', 'taro') - 読む:
$_COOKIE['name'](連想配列)
最小のサンプル
<?php
// 1. ブラウザに Cookie を書く (echo より前で呼ぶ)
setcookie('name', '太郎');
// 2. 次回以降、ブラウザが送ってきた Cookie を読む
$name = $_COOKIE['name'] ?? 'guest';
echo "こんにちは、{$name}さん\n";setcookie()はechoの前 で呼ぶ (HTTP ヘッダは本文より前に送る必要がある)- 初回アクセス時は
$_COOKIEは空 →??でguestにフォールバック - リロードすると Cookie が乗ってきて
太郎が出る
setcookie() のオプション (重要 3 つ)
setcookie(
'name', // key
'太郎', // value
[
'expires' => time() + 3600, // 1 時間後に消える
'httponly' => true, // JS から読めない (XSS 対策)
'samesite' => 'Lax', // CSRF 対策
'secure' => true, // HTTPS でのみ送る
],
);| オプション | 役割 |
|---|---|
expires | 有効期限。未指定はブラウザ閉じるまで |
httponly | JavaScript からアクセス禁止 (XSS で盗まれにくくする) |
samesite | 他サイトからのリクエストに乗せない (CSRF 対策) |
secure | HTTPS でのみ送信 |
→ 本番では httponly + samesite=Lax + secure が基本セット。
採点用スタブ: stdin から $_COOKIE を埋める
CLI 採点ランナーには ブラウザが居ない ので、$_COOKIE が自動で埋まらない。
web トピックの $_GET と同じ要領で stdin から組み立てる:
<?php
// 採点用: stdin の 1 行目 (例 "name=太郎") を $_COOKIE に展開
$line = trim(fgets(STDIN) ?: '');
parse_str($line, $_COOKIE);
// 以降は本物の Web と同じ
$name = $_COOKIE['name'] ?? 'guest';
echo "こんにちは、{$name}さん\n";parse_str("name=太郎", $_COOKIE)で連想配列に分解- 本物の Web では PHP が
$_COOKIEを自動で埋めるので、このスタブは不要
Cookie はブラウザに改ざんできる ← 必ず覚える
// ❌ 危ない例
setcookie('user_id', '42');
$userId = $_COOKIE['user_id']; // ユーザーが 1 や 999 に書き換えられる- ブラウザの開発者ツールから Cookie の値はいくらでも書き換えられる
- ログイン状態や権限など、改ざんされると困る情報を Cookie に直接置かない
- 「ユーザーが好き勝手に値を入れる入力欄」と思って扱う
→ そういう情報は Session に入れて、Cookie には Session ID (合言葉) だけ 入れる (ch02 の話)。
このチャプターでできるようになること
✅ setcookie('key', 'value') でブラウザに Cookie を書ける
✅ $_COOKIE['key'] でブラウザから送られた Cookie を読める
✅ httponly / samesite / secure の役割を 1 行で言える
✅ Cookie はブラウザに改ざんされるため、秘密情報は入れないと判断できる
→ ドリルへ
考えてみよう
既定では正解・不正解の判定はしません。自分のペースで「答えを見る」を。採点してほしい場合だけ「採点してほしい」を押してください。
ドリル 01 — stdin から $_COOKIE['name'] を組み立てて出力
問題
採点ランナーは CLI 直実行なので、answer.php の冒頭で 標準入力の 1 行を Cookie 文字列として parse_str で $_COOKIE に展開 してください (スタブはコードに含めて構いません)。
$_COOKIE['name'] を取り出し、"こんにちは、{name}さん" を 1 行出力してください。name が無ければ 'guest' をフォールバックとして使ってください。
このドリルの入力例 (tests/input.txt):
name=太郎
期待される出力:
こんにちは、太郎さん
採点
php scripts/grade.php topics/session-cookie/ch03-cookie-basic/drill/01-read-cookie/
ヒント
$line = trim(fgets(STDIN) ?: '');
parse_str($line, $_COOKIE);
$name = $_COOKIE['name'] ?? 'guest';
echo "こんにちは、{$name}さん\n";本物の Cookie 動作で確認したい場合
cd topics/session-cookie/ch03-cookie-basic/drill/01-read-cookie/ php -S localhost:8000 answer.php
ブラウザの開発者ツール (Application → Cookies) で name=太郎 を手動追加してリロード。
ドリル 02 — 複数 Cookie を読んで一覧出力
問題
採点ランナーは複数行の入力を流し込みます。各行が 1 つの Cookie (key=value) を表します。
- 各行を
parse_strで$_COOKIEに累積展開してください - 最終的な
$_COOKIEを、key=valueの形で 入力された順に 1 行ずつ出力 してください
このドリルの入力例 (tests/input.txt):
name=太郎 lang=ja theme=dark
期待される出力:
name=太郎 lang=ja theme=dark
採点
php scripts/grade.php topics/session-cookie/ch03-cookie-basic/drill/02-multiple-cookies/
ヒント
$_COOKIE = [];
while (($line = fgets(STDIN)) !== false) {
$line = trim($line);
if ($line === '') continue;
$pair = [];
parse_str($line, $pair);
$_COOKIE = array_merge($_COOKIE, $pair);
}
foreach ($_COOKIE as $k => $v) {
echo "{$k}={$v}\n";
}本物の Cookie 動作で確認したい場合
cd topics/session-cookie/ch03-cookie-basic/drill/02-multiple-cookies/ php -S localhost:8000 answer.php
ブラウザの開発者ツールから複数の Cookie を手動追加してリロード。