header

生の HTTP ヘッダを送信する

説明

void header(string $header, bool $replace = true, int $response_code = 0)

header は、生の 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
// この例は、"HTTP/" から始まる特別な場合を示しています。
// これより良い、典型的な使い方として、以下があげられます:
// 1. header($_SERVER["SERVER_PROTOCOL"] . " 404 Not Found");
//    (HTTP/1.0 を使いながら、httpステータスメッセージを上書きする)
// 2. http_response_code(404); (デフォルトのメッセージを使う)
header("HTTP/1.1 404 Not Found");
?>

2 番目の特別なヘッダは、"Location:" ヘッダです。このヘッダがブラウザに返されるだけではなく、 ブラウザに REDIRECT (302) ステータスコードを返します (2013xx ステータスコードが既に送信されていない場合にのみ)。

<?php
header("Location: http://www.example.com/"); /* ブラウザをリダイレクトします */

/* リダイレクトする際に、これ以降のコードが実行されないことを確認してください */
exit;
?>

replace

オプションのパラメータ replace は、ヘッダが 前に送信された類似のヘッダを置換するか、または、同じ形式の二番目の ヘッダを追加するかどうかを指定します。デフォルトでは、この関数は 置換を行ないますが、二番目の引数に false を指定すると、同じ型の 複数のヘッダを強制的に生成します。例えば、

<?php
header('WWW-Authenticate: Negotiate');
header('WWW-Authenticate: NTLM', false);
?>

response_code

HTTP レスポンスコードを強制的に指定の値にします。このパラメータが意味をなすのは header が空文字列でないときだけであることに注意しましょう。

戻り値

値を返しません。

エラー / 例外

ヘッダを予定通りに送信できなかった場合、 header 関数は E_WARNING レベルの警告を発生させます。

例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 を用いると、 セッションが使用された際にキャッシュ関係の正しいヘッダを 自動的に生成させることもできます。

例3 クッキーを設定する

setcookie は、クッキーを設定する便利な方法を提供します。 setcookie がサポートしていない属性をクッキーに設定する方法として、 header が使えます。

たとえば、以下のコードは Partitioned 属性を含むクッキーを設定します。

<?php
header('Set-Cookie: name=value; Secure; Path=/; SameSite=None; Partitioned;');
?>

注意

注意:

ヘッダにアクセスできたりヘッダを出力したりするのは、 それに対応した SAPI を使っている場合のみです。

注意:

出力のバッファリングを使用してこの問題を回避することができます。 この場合、ブラウザへの出力が送信するまでサーバーに 全てバッファリングされるオーバーヘッドがあります。出力バッファリングは、 ob_startob_end_flush をスクリプトでコールするか php.ini またはサーバー設定ファイルの設定ディレクティブ output_buffering を設定することにより 行うことが可能です。

注意:

実際に header が最初にコールされたか どうかにかかわらず、HTTP ステータスヘッダ行は クライアントに対し常に最初に送信されます。 HTTP ヘッダが既に送信されていない限り、 header をコールすることでステータスは 常に上書きされます。

注意:

最近のクライアントの大半は » 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 定数を使用して 手動で渡す必要があります。

参考

  • headers_sent
  • setcookie
  • http_response_code
  • header_remove
  • headers_list
  • HTTP 認証