Webサイトで複数のページを作る時、ヘッダーやフッターなどのパーツは共通化したくなりますよね。
勉強を始めたての頃はHTMLに一箇所変更が発生したら全ページを手直ししていましたが、共通化を知ってからは管理がぐっと楽になりました。いくつかやり方はありますが、今回はPHPを使って複数ページでパーツを共通化する方法をご紹介します。
ディレクトリ構成
あくまで私が管理しやすいと感じた構成ですので、皆さんの好みが見つかるまでの参考にしてください。
rootディレクトリ
├── index.php
├── assets/
│ ├── images/
│ ├── css/
│ └── js/
└── includes/
├── config.php
├── header.php
├── footer.php
└── navi.php
| ファイル | 役割 |
|---|---|
config.php |
全ページ共通の情報格納 |
header.php |
ヘッダーおよびメタ情報 |
footer.php |
フッター情報 |
navi.php |
ナビゲーション情報 |
絶対パスで読み込む
複数ページで同じコードを使い回す場合、階層が深くなっていくと相対パスでは書き分けが必要になります。ページごとに ../ の数を変えるのは事故のもとなので、絶対パスで統一するのがおすすめです。
<?php require_once __DIR__ . '/includes/config.php'; ?>
__DIR__ はそのファイルが置かれているディレクトリの絶対パスを返す定数です。どの階層のページから呼んでも同じ書き方で通るようになります。
ルートディレクトリのパスは何度も使うので、変数に入れて config.php で管理しておくと変更の際に手間が減ります。
includes/config.php の中で $root = dirname(__FILE__); と書くと、ルートではなく includes フォルダのパスが入ります。その状態で $root . '/includes/header.php' と書くと includes/includes/header.php を探しにいってしまい、ファイルが見つかりません。includes の1つ上を指すよう dirname(__DIR__) と書いてください。
include と require の使い分け
| 構文 | 読み込みに失敗したとき |
|---|---|
include |
警告を出すが、後続の処理を続ける |
require |
致命的エラーとなり、処理を中断する |
軽微なエラーが許され後続処理を続けたい場合は include、読み込めなければページが成立しない場合は require を使うのが適切です。
ヘッダーやフッター、設定ファイルは「なければページが壊れる」ものなので、基本は require を使っておくほうが安全です。読み込みに失敗しても中途半端なページが表示されてしまう include より、はっきり止まってくれたほうが原因に気づけます。
_once 付きの構文
include_once と require_once は、同じファイルがすでに読み込まれている場合は二度読み込まない構文です。設定ファイルのように、変数の定義が二重に走ると困るものに使います。
require_once __DIR__ . '/includes/config.php';
サンプルコード
config.php
全ページ共通の変数を管理するファイルです。
<?php
// このファイルは includes/ にあるので、1つ上がルートディレクトリ
$root = dirname(__DIR__);
$title = 'サイト名';
$description = 'サイトの説明文';
文字列は必ずクォートで囲んでください。$title = サイト名; のようにクォートなしで書くと、PHPは定数として解釈しようとして「Undefined constant」の致命的エラーになります。
index.php
各ページの本体です。最初に config.php を読み込むことで、以降のファイルで $root や $title が使えるようになります。
<?php require_once __DIR__ . '/includes/config.php'; ?>
<?php require($root . '/includes/header.php'); ?>
<main>
<h1>ページの内容</h1>
<p>ここにページごとの中身を書きます。</p>
</main>
<?php require($root . '/includes/footer.php'); ?>
ページごとにタイトルを変えたい場合は、config.php を読み込んだ後、header.php を読み込む前に $title = 'このページのタイトル'; と上書きしてください。読み込む順番が結果を決めます。
header.php
<head> に入る内容からヘッダー要素までのまとめです。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo $title; ?></title>
<meta name="description" content="<?php echo $description; ?>">
<!-- SNS シェア用 OGP -->
<meta property="og:title" content="<?php echo $title; ?>">
<meta property="og:description" content="<?php echo $description; ?>">
<meta property="og:image" content="/assets/images/ogp.jpg">
<meta property="og:type" content="website">
<meta property="og:url" content="https://example.com/">
<!-- Twitterカード -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@youraccount">
<!-- ファビコン -->
<link rel="icon" href="/assets/images/favicon.ico">
<!-- CSS 読み込み -->
<link rel="stylesheet" href="/assets/css/style.css">
</head>
<body>
<header>
<div class="site-header">
<div class="logo">
<a href="/"><img src="/assets/images/logo.png" alt="サイト名"></a>
</div>
<?php require($root . '/includes/navi.php'); ?>
</div>
</header>
navi.php
ナビゲーション要素のまとめです。header.php から読み込まれます。
<nav class="global-nav">
<ul>
<li><a href="/">ホーム</a></li>
<li><a href="/about/">会社概要</a></li>
<li><a href="/service/">サービス</a></li>
<li><a href="/news/">ニュース</a></li>
<li><a href="/contact/">お問い合わせ</a></li>
</ul>
</nav>
footer.php
フッターのナビゲーションからコピーライト、JavaScriptの読み込みまでをまとめています。
<footer>
<div class="site-footer">
<nav class="footer-nav">
<ul>
<li><a href="/privacy/">プライバシーポリシー</a></li>
<li><a href="/terms/">利用規約</a></li>
<li><a href="/contact/">お問い合わせ</a></li>
<li><a href="/sitemap/">サイトマップ</a></li>
</ul>
</nav>
<p class="copyright">
© <?php echo date('Y'); ?> サイト名 All Rights Reserved.
</p>
</div>
</footer>
<!-- JS 読み込み -->
<script src="/assets/js/main.js"></script>
</body>
</html>
コピーライトの年を date('Y') で出力しておくと、年が変わったときの修正が不要になります。地味ですが、毎年どこかのページで直し忘れる作業がなくなります。
動かないときの確認ポイント
- ファイルの拡張子が
.phpになっているか —.htmlのままではPHPが実行されません - サーバーがPHPに対応しているか — ローカルで開いてもコードがそのまま表示される場合、PHPが動く環境ではありません
$rootが定義される前に使っていないか —config.phpを最初に読み込んでください- 読み込むファイル名が実在するか — パスの綴りミスは
requireにしておくとエラーで気づけます
よくある質問
HTMLファイルのままでもincludeは使えますか?
使えません。PHPはサーバー側で処理される言語なので、ファイルの拡張子を .php にする必要があります。サーバーの設定で .html でもPHPを処理させることは可能ですが、まずは素直に .php にするのが確実です。
拡張子をphpにするとSEOで不利になりませんか?
不利にはなりません。検索エンジンが見るのは出力されたHTMLで、拡張子は評価の対象ではありません。ただし公開後にURLを .html から .php へ変更する場合は、旧URLからのリダイレクト設定を忘れないでください。
includeとrequireはどちらを使うべきですか?
ヘッダーやフッター、設定ファイルなど、読み込めなければページが成立しないものは require が適しています。読み込みに失敗したときにはっきり止まってくれるため、原因に気づきやすくなります。なくても表示に影響しない補助的なパーツであれば include でも構いません。
ページごとにタイトルやディスクリプションを変えられますか?
変えられます。config.php を読み込んだ後、header.php を読み込む前に $title や $description を上書きしてください。あとから代入した値が使われるので、共通の初期値を config.php に、ページ固有の値を各ページに書く形になります。
まとめ
| 項目 | 解説 |
|---|---|
| ディレクトリ構成 | includes フォルダに共通パーツを集約 |
| 絶対パスでの読み込み | __DIR__ を使って全ページ同じ記述にする |
| ルートの取得 | includes の中では dirname(__DIR__) |
| include / require | エラー時の挙動が異なる(継続 vs 中断) |
| include_once / require_once | ファイルの重複読み込みを防ぐ |
PHPの include はとても基本的な構文ですが、コードを分割して整理する第一歩です。共通パーツを1か所にまとめることで修正作業が大幅に楽になり、ページ数が多いサイトほど恩恵を感じると思います。
最初は小さなサイトでも実際に使ってみて、メンテナンス性の向上を体験してみてください。
