Warning: Cannot modify header information – headers already sent …
こういうエラーメッセージを見ることはないだろうか。これはPHPプログラムからHTMLヘッダを吐き出す際にしばしば見られるエラーだ。
HTTPの仕様の話になるが、HTTPレスポンス(ブラウザからのリクエストに対する返答)はヘッダと本文にわかれる。本文とはいわゆるHTMLデータのことで、ヘッダとは本文を送るに際してあらかじめ送出しておくべき内容だ。HTML自体はブラウザの「ソースを見る」で表示させることができるが、ヘッダは別途ソフトを入れない限り見ることができないので、若干なじみが薄い。
ここで上記のメッセージに戻る。このエラーはヘッダ情報を送出しようとしたところ「すでに本文を出力してるからエラーです」といっているのだ。例えば以下のようにするとエラーになる。
<?php
print(‘test’);
header(‘Content-type: text/html’);
?>
プログラム1行目で本文を送出しているにもかかわらず、2行目でヘッダを送出しようとしているからだ。これはバグだ。
このような明らかな場合は、すぐにエラー箇所を発見できるが、発見が難しい場合もある。例えば以下のようにファイルをインクルードする場合を考える。
<?php
include(‘myfile.php’);
header(‘Content-type: text/html’);
?>
インクルード元のmyfile.phpでprint();などとするとエラーになるのは当然だが、そのファイルの文末、つまり?>の後ろに改行や空白があるだけでも上記と同じエラーが出るのだ。このエラーを見つけるのは結構面倒。
そこで対策(目からうろこ)。PHPの閉じタグ「?>」を記述しない。PHPは文法上、閉じタグを書かなくてもOKなのだ。これで余計な改行や空白文字が入る(ブラウザに送出される)ということはなくなる。盲点だけど、すごく便利な裏技だ。