headers_sent(バグ発見器)
PHP でフォーム処理をするにあたって
POST 送信先を処理用ファイルにして、
最後に元ファイルへ飛ばして、更新がちゃんとされているか確認できるようにすることが多い。
この際、header 関数を用いて
- header('Location: http://www.example.com/’);
などとするのだが、
header 関数は結構曲者で、
・header 関数より以前に HTML で出力している
・header 関数より以前にecho or print 文を使用している
・< ? の前に空白がある
に当てはまると
- header already sent
とエラーが出る。
以上とは別に
・header 関数より以前に include or require 文を使用している
これもエラーになるという記事をあちこちで見たが、
私自身が利用する場合に、include or require 文を使用していても
header 関数を利用可能な場合があり、どうもおかしいと思っていた。
本日も同じ症状にはまっていたのだが、PHP マニュアルにて素敵なものを発見した。
headers_sent() 関数である。
- // オプションの file と line パラメータの使用例(PHP4.3.0以降)
- // $filename と $linenum が後で使用されていることに注目。
- // これらの変数に事前に値を与えたりしてはいけません。
- if (!headers_sent($filename, $linenum)) {
- header('Location: http://www.example.com/');
- exit;
- // おそらく、ここでエラー処理を行うでしょう。
- } else {
- echo "$filename の $linenum 行目でヘッダがすでに送信されています。\n" .
- "リダイレクトできません。代わりにこの <a " .
- "href=\"http://www.example.com\">リンク</a> をクリックしてください。\n";
- exit;
- }
これを利用すると、既に header 送信している場所を特定してくれるのだ。
本日、これを利用してみたところ、
require 先のファイルの最終行 ?> の後ろに、まんまと半角スペースが1つ見つかった。
これを削除したところ、require文の後ろに置いたheader関数が、希望通り動作してくれた。