MENU

PHPで理解するリダイレクトとHTTPヘッダー

目次

はじめに: リダイレクトはHTTPヘッダーでブラウザに伝える

PHPでログイン処理やフォーム送信を作っていると、処理が終わったあとに別のページへ移動したい場面があります。ログインに成功したらマイページへ移動する、お問い合わせ送信後に完了ページへ移動する、といった流れです。

このときよく使うのが、PHPの header('Location: ...') です。

<?php
header('Location: mypage.php');
exit;

一見すると、PHPが直接ページを切り替えているように見えるかもしれません。しかし実際には、サーバーがHTTPレスポンスヘッダーで「このURLへ移動してください」とブラウザへ伝えています。

つまり、リダイレクトはHTMLの表示ではなく、HTTPの仕組みです。HTTPヘッダーとステータスコードを理解すると、PHPの画面遷移や「headers already sent」のようなエラーも見えやすくなります。

リダイレクトは、サーバーがHTTPレスポンスでブラウザに移動先を伝える仕組みです。

HTTPヘッダーとは何か

HTTP通信では、リクエストやレスポンスに本文だけでなく、ヘッダーと呼ばれる情報が含まれます。

レスポンス本文がHTMLやJSONの中身だとすると、ヘッダーはその中身をどう扱うかを伝える情報です。

たとえば、次のようなヘッダーがあります。

Content-Type  → 本文の種類を伝える
Location      → リダイレクト先を伝える
Set-Cookie    → Cookieを保存するよう伝える
Cache-Control → キャッシュの扱いを伝える

ブラウザは、レスポンスヘッダーを見て処理を判断します。本文をHTMLとして読むのか、JSONとして読むのか、Cookieを保存するのか、別のURLへ移動するのか、といった判断です。

PHPの header() は、このHTTPレスポンスヘッダーを設定するための関数です。画面に文字を表示する関数ではなく、ブラウザへ渡すメタ情報を設定する関数だと考えると分かりやすくなります。

HTTPヘッダーは、本文とは別に、通信の扱い方をブラウザやサーバーへ伝える情報です。

リダイレクトはサーバーからの移動指示

リダイレクトは、サーバーがブラウザへ「別のURLへ移動してください」と伝える仕組みです。

流れを簡単に表すと、次のようになります。

ブラウザ  →  サーバーへリクエスト
サーバー  →  Locationヘッダーで移動先を返す
ブラウザ  →  移動先URLへ再度リクエスト

たとえば、ログイン成功後にマイページへ移動する場合、サーバーはマイページのHTMLをその場で返すのではなく、Location: mypage.php のようなヘッダーを返します。ブラウザはそれを受け取り、改めて mypage.php にアクセスします。

この仕組みは、ログイン後の移動だけでなく、フォーム送信後の完了ページ、古いURLから新しいURLへの移動、HTTPからHTTPSへの移動などでも使われます。

リダイレクトでは、サーバーが移動先を返し、ブラウザが改めてそのURLへリクエストを送ります。

PHPでリダイレクトする

PHPでリダイレクトする基本形は、header('Location: ...')exit の組み合わせです。

<?php
header('Location: thanks.php');
exit;

Location ヘッダーで移動先を指定し、exit で処理を終了します。exit を書かないと、その下にある処理が続いてしまう可能性があります。

ログイン成功後なら、次のように使えます。

<?php
session_start();

// ログイン成功後の処理
$_SESSION['user_id'] = 1;

header('Location: mypage.php');
exit;

フォーム送信後にもリダイレクトはよく使われます。POSTで送信された内容を処理したあと、完了ページへ移動させることで、ブラウザの再読み込みによる二重送信を避けやすくなります。

<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // 保存やメール送信などの処理

    header('Location: thanks.php');
    exit;
}

このように、POST処理後にGETの完了ページへ移動する考え方は、Post/Redirect/Getと呼ばれることがあります。

PHPでリダイレクトしたあとは、後続処理が続かないように exit で処理を終了します。

header() は出力前に呼ぶ

PHPの header() でつまずきやすいのが、出力前に呼ぶ必要があるという点です。

HTTPレスポンスは、大まかにいうとヘッダーが先、本文が後に送られます。ブラウザへHTML本文を送り始めたあとで、あとからヘッダーを変更することはできません。

そのため、次のようなコードは問題になります。

<!doctype html>
<html lang="ja">
<?php
header('Location: mypage.php');
exit;

HTMLを出力したあとに header() を呼んでいるため、ヘッダーを変更できない可能性があります。このとき、headers already sent のような警告が出ることがあります。

正しくは、画面に何かを出力する前に header() を呼びます。

<?php
header('Location: mypage.php');
exit;
?>
<!doctype html>
<html lang="ja">

実務では、PHPファイルの先頭に余計な空白が入っていたり、BOM付きUTF-8で保存されていたりするだけでも、意図せず出力が始まることがあります。リダイレクトやCookie設定がうまくいかないときは、出力の前にヘッダーを送れているか確認します。

HTTPヘッダーは本文より先に送る必要があるため、PHPの header() は画面出力より前に呼びます。

ステータスコードとリダイレクト

リダイレクトでは、Location ヘッダーとあわせて、3xx系のHTTPステータスコードが使われます。

代表的なものは次のとおりです。

301  → 恒久的な移動
302  → 一時的な移動
303  → POST後に別URLをGETで見に行かせる場面で使われる
307  → 一時的な移動だがメソッドを変えない
308  → 恒久的な移動だがメソッドを変えない

PHPで単に header('Location: ...') と書いた場合、多くの環境では一時的なリダイレクトとして扱われます。明示したい場合は、ステータスコードも指定できます。

<?php
header('Location: /new-page.php', true, 301);
exit;

ただし、301は恒久的な移動としてブラウザや検索エンジンに記憶されることがあるため、学習中や一時的な画面遷移では慎重に使います。

フォーム送信後に完了ページへ移動する場合は、303を使って「次はGETで見に行ってください」と表すこともあります。

<?php
header('Location: thanks.php', true, 303);
exit;

リダイレクトでは、Locationヘッダーとあわせて、移動の意味を表す3xx系ステータスコードが使われます。

よく使うHTTPヘッダーをPHPで見る

PHPの header() は、リダイレクト以外にも使われます。

JSONを返すAPIでは、本文がJSONであることを伝えるために Content-Type を設定します。

<?php
header('Content-Type: application/json; charset=UTF-8');

echo json_encode([
    'message' => 'ok',
], JSON_UNESCAPED_UNICODE);

キャッシュの扱いを指定することもできます。

<?php
header('Cache-Control: no-store');

Cookieを設定する場合は、setcookie() を使うことが多いです。これも内部的には、ブラウザへ Set-Cookie ヘッダーを送る処理です。

<?php
setcookie('theme', 'dark', time() + 3600);

このように、HTTPヘッダーはWebアプリの見えないところでたくさん使われています。リダイレクト、JSON、Cookie、キャッシュは、すべてレスポンスヘッダーと関係します。

PHPでは header() を使って、Content-TypeやCache-ControlなどのHTTPレスポンスヘッダーを設定できます。

試験ではどう問われるか

基本情報技術者試験では、HTTPヘッダー、ステータスコード、Cookie、キャッシュなどが関連して問われることがあります。

リダイレクトは、3xx系のステータスコードと Location ヘッダーの組み合わせとして理解しておくと整理しやすいです。サーバーが移動先を返し、ブラウザがそのURLへ再度リクエストを送ります。

また、Content-Type は本文の種類、Set-Cookie はCookie保存、Cache-Control はキャッシュ制御に関係します。ヘッダーは本文とは別に通信の扱いを伝える情報だと押さえると、問題文を読みやすくなります。

試験では、リダイレクトをHTTPレスポンスヘッダーと3xx系ステータスコードの組み合わせとして理解することが大切です。

実務ではどう使われるか

実務では、リダイレクトはさまざまな場面で使われます。

ログインに成功したらマイページへ移動する、ログインしていないユーザーをログインページへ戻す、権限がないユーザーを別ページへ移動する、といった制御です。

フォーム送信後の二重送信防止にも使われます。POST処理が終わったあとに完了ページへリダイレクトすると、再読み込みしてもPOSTが繰り返されにくくなります。

URLの正規化でも使います。たとえば、古いURLから新しいURLへ移動する、HTTPでアクセスされたらHTTPSへ移動する、末尾スラッシュの有無をそろえる、といった場面です。

ただし、リダイレクト先をユーザー入力から直接決める場合は注意が必要です。外部サイトへ自由に飛ばせる作りにすると、フィッシングなどに悪用される可能性があります。移動先は許可したURLだけにするなど、制限を設けるのが安全です。

実務では、リダイレクトを使って、処理後の画面遷移やURLの整理、セキュリティ上の誘導を行います。

まとめ: ヘッダーを理解するとPHPの画面遷移が分かる

リダイレクトは、サーバーがHTTPレスポンスでブラウザに移動先を伝える仕組みです。PHPでは header('Location: ...') を使って、Location ヘッダーを送れます。

header() は画面に文字を表示する関数ではなく、HTTPレスポンスヘッダーを設定する関数です。ヘッダーは本文より先に送る必要があるため、HTMLや空白を出力する前に呼びます。

リダイレクトでは、Location ヘッダーと3xx系ステータスコードが関係します。ログイン後の移動、フォーム送信後の完了ページ、URL変更、HTTPSへの移動など、実務でも多くの場面で使われます。

HTTPヘッダーを理解すると、PHPでページ移動やレスポンス制御を行う仕組みが見えやすくなります。

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

この記事を書いた人

20代前半に、ゲームボーイアドバンス、ニンテンドーDS、Wii向けソフトの開発に携わりました。

その後、20代後半にかけては組み込み系エンジニアとして、主にサーバーソフトウェアの開発を経験。

30代からはWebエンジニアとして、さまざまなWebサービスの開発に携わってきました。

現在は40代となり、ゲーム開発、組み込み開発、Web開発で培った経験を活かしながら、技術をわかりやすく伝える活動にも取り組んでいます。

コメント

コメントする

CAPTCHA


目次