🇯🇵 日本語 | 🇺🇸 English | 🇪🇸 Español | 🇵🇹 Português | 🇹🇭 ไทย | 🇨🇳 中文

【PHP入門】ページの切り替え自由自在!簡単なルーターを作って仕組みを理解しよう

これまでの学習で、PHPを使ってデータベースから情報を取得し、動的なページを生成できるようになりました。しかし、Webサイトには「トップページ」「会社概要」「お問い合わせ」など、複数の異なるページが存在するのが普通です。これらのページを、ヘッダーやフッターを共通化しつつ、効率的に管理するにはどうすればよいのでしょうか?

その答えが「ルーティング」という考え方です。ルーティングとは、ユーザーがアクセスしたURLに応じて、表示するコンテンツを切り替える「交通整理」の役目を担う仕組みです。この記事では、`index.php?page=about`のようなURLパラメータを使い、PHPでごく簡単なルーターを自作します。Laravelなどの本格的なフレームワークが裏側で何をやっているのか、その核心部分に触れることで、Webアプリケーションの構造への理解を深め、次の学習への大きな一歩としましょう!

PHPを動かすための準備(開発環境)まだXAMPP「ザンプ」を構築してない方は、【PHP入門】XAMPPのダウンロードとインストール方法を徹底解説!を参照してください。 インストール後、指定されたフォルダ(`htdocs`など)にPHPファイルを置けば、準備は完了です!

1. ルーティングの仕組みとは?PHPによる交通整理

ルーティングの仕組みは、大きなビルの受付案内係に例えることができます。訪問者(ユーザー)は皆、まず同じ正面玄関(index.php)にやってきます。そして、受付(ルーター)に「〇〇部に行きたいです(`?page=about`)」と告げます。すると、受付は行き先に応じて適切な部署(about.php)へと案内してくれます。

この仕組みを作るために、PHPの以下の3つの要素を使います。

  1. $_GET変数: URLの末尾に付いている?page=aboutのような「クエリ文字列」から、pageの値(この場合は`about`)を受け取るためのPHPの特殊な変数です。
  2. include: 別のPHPファイルの内容を、指定した場所に読み込んで合体させる命令です。これにより、ヘッダーやフッターを共通化できます。
  3. file_exists()関数: 悪意のあるURLが指定された場合に備え、読み込もうとしているファイルが実際にサーバーに存在するかどうかをチェックする、セキュリティ上とても重要な関数です。

これらの部品を組み合わせることで、URLに応じて表示内容を切り替えるルーターが完成します。

2. 実践!簡易ルーターを3つのファイルで作る

それでは、実際に簡易ルーターを作ってみましょう。今回は以下の3つのファイルを用意し、すべて同じフォルダに保存してください。

ファイル1: index.php (ルーター兼レイアウト)

このファイルが、私たちのサイトの「正面玄関」です。ナビゲーションなどの共通部分と、URLに応じて中身が切り替わるコンテンツ表示エリアを持ちます。これが「まるっと動く完全HTMLの例」になります。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>簡易ルーターのサイト</title>
    <style>
        body { font-family: sans-serif; line-height: 1.8; }
        .container { max-width: 800px; margin: 20px auto; padding: 20px; border: 1px solid #ddd; }
        nav { background: #f0f0f0; padding: 10px; margin-bottom: 20px; }
        nav a { margin-right: 15px; text-decoration: none; color: #0056b3; }
        nav a:hover { text-decoration: underline; }
        .content { border-top: 2px solid #eee; padding-top: 20px; }
        footer { margin-top: 30px; text-align: center; font-size: 0.9em; color: #777; }
        .not-found { color: red; font-weight: bold; }
    </style>
</head>
<body>
    <div class="container">
        <header>
            <h1>簡易ルーターのサンプルサイト</h1>
        </header>
        <nav>
            <a href="index.php?page=home">ホーム</a>
            <a href="index.php?page=about">このサイトについて</a>
        </nav>

        <div class="content">
            <?php
            // 1. URLパラメータから表示するページ名を取得
            //    パラメータがない場合は 'home' をデフォルトとする
            $page = $_GET['page'] ?? 'home';

            // 2. 表示を許可するページのリスト(ホワイトリスト)
            $allowed_pages = ['home', 'about'];

            // 3. ページ名が許可リストに含まれているかチェック
            if (in_array($page, $allowed_pages)) {
                // 4. 対応するファイルパスを作成
                $file_path = $page . '.php';

                // 5. ファイルが存在するか最終確認してから読み込む
                if (file_exists($file_path)) {
                    include($file_path);
                } else {
                    echo '<p class="not-found">エラー: ファイルが見つかりません。</p>';
                }
            } else {
                // 許可されていないページが指定された場合
                echo '<p class="not-found">404 Not Found: 指定されたページは存在しません。</p>';
            }
            ?>
        </div>

        <footer>
            <p>© 2025 Simple Router Inc.</p>
        </footer>
    </div>
</body>
</html>

ファイル2: home.php (ホームのコンテンツ)

`index.php`に読み込まれる、ホーム(トップページ)の内容だけが書かれたファイルです。

<h2>ようこそ!</h2>
<p>ここはホームページです。</p>
<p>上のナビゲーションをクリックすると、URLの ?page= の値が変化し、表示されるコンテンツが切り替わります。</p>

ファイル3: about.php (サイトについてのコンテンツ)

同様に、`index.php?page=about`が指定されたときに読み込まれる内容です。

<h2>このサイトについて</h2>
<p>このサイトは、PHPの簡易的なルーティングの仕組みを学ぶためのサンプルです。</p>
<p>index.phpが土台となり、URLパラメータに応じてこのabout.phpなどの異なるファイルの内容を動的に読み込んでいます。</p>

これで準備完了です。ブラウザで`index.php`にアクセスしてみてください。ナビゲーションのリンクをクリックするたびに、中央のコンテンツだけが「ホーム」と「このサイトについて」で切り替わるのが確認できるはずです。

3. 気をつけるべき点:ディレクトリトラバーサル攻撃

簡易ルーターを自作する上で、絶対に知っておかなければならないのが**ディレクトリトラバーサル**という攻撃です。もし、セキュリティ対策をせずに以下のようなコードを書いてしまうと、非常に危険です。

<?php
// 悪い例:絶対に真似しないでください!
$page = $_GET['page'];
include($page . '.php'); // ユーザーの入力を検証せずにそのまま使っている
?>

このコードでは、攻撃者がURLに `?page=../../../../etc/passwd` のような特殊な文字列を指定することで、サーバー上の本来アクセスしてはいけない重要な設定ファイルなどを読み取れてしまう可能性があります。

この攻撃を防ぐために、私たちの`index.php`の例では2段階のチェックを入れています。

  1. **ホワイトリスト方式**: `$allowed_pages`という許可リストを作り、指定されたページ名がその中にあるか`in_array()`でチェックする。
  2. **ファイルの存在確認**: 許可リストを通過しても、念のため`file_exists()`でファイルが実際に存在するかを最終確認する。

この対策により、意図しないファイルが読み込まれるのを防ぎ、安全性を高めています。

4. まとめと次のステップ

今回は、URLパラメータとPHPの`include`文を使って、表示するコンテンツを切り替える簡易的なルーティングの仕組みを学びました。`index.php`という一つの入り口が、URLに応じて交通整理を行うことで、Webサイト全体が構成されるという感覚が掴めたでしょうか。

実は、私たちが普段使っているLaravelやSymfonyといったモダンなPHPフレームワークは、このルーティングの仕組みをさらに高度で安全にしたものを提供しています。今回の知識は、そうしたフレームワークがなぜ必要なのか、裏側で何が行われているのかを理解するための重要な基礎となります。

次のステップとしては、`.htaccess`ファイルを使ってURLを書き換え、`index.php?page=about`のようなURLを`/about`のように、より美しく見せる「**プリティURL**」に挑戦してみるのも面白いでしょう。Webの仕組みへの理解がさらに深まるはずです。