はじめに
setcookie() は Cookie を送信する関数として有名ですが、注意すべきは 「出力より前に呼び出さなければならない」 という点です。
今回は、問題集に掲載されていたコード例をもとに、setcookie() の実際の動作と「誤りとなるケース」を整理してみます。
目次
🧩 まずは問題のコード
<?php
declare(strict_types=1);
error_reporting(-1);
var_dump(ini_get('output_buffering'));
var_dump($_COOKIE);
setcookie('name', 'val');このコードをブラウザ経由で実行すると、問題集では次のように説明されていました。
1回目:
string(0) ""
array(0) { }
2回目:
string(0) ""
array(1) {
["name"] => string(3) "val"
}一見「正常にCookieがセットされているように見える」説明ですが、実際に実行すると次のような警告が出ます👇
Warning: Cannot modify header information - headers already sent by
(output started at /var/www/html/part2/p183.php:5)⚠️ 何が問題なのか?
setcookie() は、HTTPヘッダに Set-Cookie を追加してブラウザに送信する関数です。
ところが var_dump() や echo などの出力関数を 先に実行すると、すでに本文(body)出力が始まってしまう ため、ヘッダの送信が不可能になります。
その結果:
- PHPは「ヘッダはすでに送信された(headers already sent)」という警告を出す
- Cookieヘッダは送られない
- ブラウザ側にCookieは保存されず、次回アクセス時にも
$_COOKIEは空のまま
✅ 正しい書き方
出力より前に setcookie() を呼び出すようにします。
<?php
declare(strict_types=1);
error_reporting(-1);
setcookie('name', 'val');
var_dump(ini_get('output_buffering'));
var_dump($_COOKIE);この順序なら:
1回目のアクセス
string(0) ""
array(0) { }2回目のアクセス
string(0) ""
array(1) {
["name"] => string(3) "val"
}となり、Cookie が正しく送信・保存されます。
🧠 図解:HTTPヘッダと本文の流れ
❌ 【誤った順序】
┌──────────────────────────────────┐
│ 出力(var_dumpなど) │ → 本文送信開始!
├──────────────────────────────────┤
│ setcookie() 呼び出し │ → ヘッダ送信はもうできない!
└──────────────────────────────────┘
↓
⚠️ Warning: headers already sent✅ 【正しい順序】
┌──────────────────────────────────┐
│ setcookie() 呼び出し │ → ヘッダに Set-Cookie 追加
├──────────────────────────────────┤
│ 出力(var_dumpなど) │ → 本文送信開始(ヘッダ済み)
└──────────────────────────────────┘
↓
🍪 Cookieがブラウザに保存される🔍 補足:出力バッファリングが有効な場合
output_buffering や ob_start() により出力が一時的にバッファされている場合、var_dump() の後でも setcookie() が成功するように見えることがあります。
しかしこれはあくまで例外的挙動であり、明示的に保証されているわけではありません。
テストや本番環境では、必ず 出力前に setcookie() を記述するのが安全です。
🧾 まとめ
| 状況 | 結果 | 説明 |
|---|---|---|
var_dump() → setcookie() | ❌ 警告発生・Cookie送信失敗 | 出力後のためヘッダ送信不可 |
setcookie() → var_dump() | ✅ 正常にCookie送信 | 出力前にヘッダ送信完了 |
