(PHP 4, PHP 5, PHP 7)
header — 生の HTTP ヘッダを送信する
$header
[, bool $replace
= TRUE
[, int $http_response_code
]] ) : voidheader() は、生の HTTP ヘッダを送信するために使用されます。 HTTP ヘッダについての詳細な情報は » HTTP/1.1 仕様 を参照ください。
覚えておいて頂きたいのは、header() 関数は、 通常の HTML タグまたは PHP からの出力にかかわらず、すべての実際の 出力の前にコールする必要があることです。 頻出するエラーとして、include または require 関数、他のファイルをアクセスする関数に 空白または空行があり、header() の前に出力が 行われてしまうというものがあります。同じ問題は、単一の PHP/HTML ファイルを使用している場合でも存在します。
<html>
<?php
/* これはエラーとなります。この上に出力があることに注目してください。
* それはheader()のコールより前であるということになります */
header('Location: http://www.example.com/');
exit;
?>
header
ヘッダ文字列。
特殊な header コールが 2 種類あります。最初のものは、 文字列 "HTTP/" から始まる全てのヘッダ (大文字・小文字は区別されません) です。 このヘッダは、送信する HTTP ステータスコードを示すために使用されます。 例えば、存在しないファイルへのリクエストを処理するためにある PHP スクリプトを使用するよう (ErrorDocument ディレクティブにより) Apache を設定する場合、 そのスクリプトが正しいステータスコードを返すようにする必要があります。
<?php
header("HTTP/1.0 404 Not Found");
?>
2 番目の特別なヘッダは、"Location:" ヘッダです。このヘッダがブラウザに返されるだけではなく、 ブラウザに REDIRECT (302) ステータスコードを返します (201 や 3xx ステータスコードが既に送信されていない場合にのみ)。
<?php
header("Location: http://www.example.com/"); /* ブラウザをリダイレクトします */
/* リダイレクトする際に、これ以降のコードが実行されないことを確認してください */
exit;
?>
replace
オプションのパラメータ replace
は、ヘッダが
前に送信された類似のヘッダを置換するか、または、同じ形式の二番目の
ヘッダを追加するかどうかを指定します。デフォルトでは、この関数は
置換を行ないますが、二番目の引数に FALSE
を指定すると、同じ型の
複数のヘッダを強制的に生成します。例えば、
<?php
header('WWW-Authenticate: Negotiate');
header('WWW-Authenticate: NTLM', false);
?>
http_response_code
HTTP レスポンスコードを強制的に指定の値にします。このパラメータが意味をなすのは
header
が空文字列でないときだけであることに注意しましょう。
値を返しません。
バージョン | 説明 |
---|---|
5.1.2 | この関数は一度に複数のヘッダを送信できないようになりました。 これは、ヘッダインジェクション攻撃への対策です。 |
例1 ダウンロードダイアログ
PDF ファイルを生成した場合など、 それをダウンロードするかの確認ダイアログを表示させたいことがあるでしょう。 そんな場合は、» Content-Disposition ヘッダを使用してファイル名を指定すると、ブラウザ側でダイアログを表示させることができます。
<?php
// PDFを出力します
header('Content-Type: application/pdf');
// downloaded.pdf という名前で保存させます
header('Content-Disposition: attachment; filename="downloaded.pdf"');
// もとの PDF ソースは original.pdf です
readfile('original.pdf');
?>
例2 キャッシュディレクティブ
PHP スクリプトはしばしば動的に HTML を生成するため、クライアント ブラウザやサーバーおよびクライアントブラウザの間でプロキシがキャッシュを 行ったりするべきではありません。多くのプロキシとクライアントでは、 以下のコードにより強制的にキャッシュを無効にできます。
<?php
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // 過去の日付
?>
注意:
上記のヘッダを全て出力しなかったとしてもページのキャッシュが 行われない場合があることに気付くかもしれません。デフォルトの ブラウザのキャッシュの動作をユーザーが変更できる手段はいくつもあります。 上記のヘッダを送信することにより、スクリプトの出力がキャッシュされる 可能性がある設定を上書きするべきです。
さらに、session_cache_limiter() および 設定 session.cache_limiter を用いると、 セッションが使用された際にキャッシュ関係の正しいヘッダを 自動的に生成させることもできます。
注意:
ヘッダにアクセスできたりヘッダを出力したりするのは、 それに対応した SAPI を使っている場合のみです。
注意:
出力のバッファリングを使用してこの問題を回避することができます。 この場合、ブラウザへの出力が送信するまでサーバーに 全てバッファリングされるオーバーヘッドがあります。出力バッファリングは、 ob_start() と ob_end_flush() をスクリプトでコールするか php.ini またはサーバー設定ファイルの設定ディレクティブ output_buffering を設定することにより 行うことが可能です。
注意:
実際に header() が最初にコールされたか どうかにかかわらず、HTTP ステータスヘッダ行は クライアントに対し常に最初に送信されます。 HTTP ヘッダが既に送信されていない限り、 header() をコールすることでステータスは 常に上書きされます。
注意:
Microsoft Internet Explorer 4.01 にはバグがあり、 この方法が動作しません。これを解決する方法はありません。 同様に Microsoft Internet Explorer 5.5 にもこれを妨げるバグがあります。 こちらは、サービスパック 2 以降にアップグレードすることで対応できます。
注意: セーフモードが有効な場合は、 WWW-Authenticate ヘッダ (HTTP 認証に使用する) を設定した際に、スクリプトの uid が realm 部に追加されます。
注意:
最近のクライアントの大半は » Location: への引数として相対 URI も受け付けますが、 古いクライアントの中にはスキームとホスト名そして絶対パスを含む絶対 URL しか受け付けないものもあります。 通常は、相対 URI から絶対 URI を作成するためには $_SERVER['HTTP_HOST']、 $_SERVER['PHP_SELF'] および dirname() を使用できます。
<?php
/* カレントディレクトリの別のページにリダイレクトします */
$host = $_SERVER['HTTP_HOST'];
$uri = rtrim(dirname($_SERVER['PHP_SELF']), '/\\');
$extra = 'mypage.php';
header("Location: http://$host$uri/$extra");
exit;
?>
注意:
session.use_trans_sid が有効であったとしても、セッション ID が Location ヘッダとともに 渡されることはありません。
SID
定数を使用して 手動で渡す必要があります。