《PHP8上級試験対策》setcookie()の前に出力処理を入れるとどうなる?

  • URLをコピーしました!

はじめに

setcookie() は Cookie を送信する関数として有名ですが、注意すべきは 「出力より前に呼び出さなければならない」 という点です。
今回は、問題集に掲載されていたコード例をもとに、setcookie() の実際の動作と「誤りとなるケース」を整理してみます。

キーワード: setcookie / ヘッダ送信 / headers already sent / 出力バッファ / クッキー送信失敗

目次

🧩 まずは問題のコード

<?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_bufferingob_start() により出力が一時的にバッファされている場合、
var_dump() の後でも setcookie() が成功するように見えることがあります。

しかしこれはあくまで例外的挙動であり、明示的に保証されているわけではありません。
テストや本番環境では、必ず 出力前に setcookie() を記述するのが安全です。

🧾 まとめ

状況結果説明
var_dump()setcookie()❌ 警告発生・Cookie送信失敗出力後のためヘッダ送信不可
setcookie()var_dump()✅ 正常にCookie送信出力前にヘッダ送信完了

この記事が気に入ったら
いいねしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次