TOP ──BLOG ──Web

PHPのincludeでヘッダー・フッターを共通化する

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>

ナビゲーション要素のまとめです。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">
        &copy; <?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か所にまとめることで修正作業が大幅に楽になり、ページ数が多いサイトほど恩恵を感じると思います。

最初は小さなサイトでも実際に使ってみて、メンテナンス性の向上を体験してみてください。

あわせて読みたい

代表 morino のポートレート

この記事を書いた人

morino

Webサイト・ECサイト制作、SNS運用、体験型ゲーム制作をひとりで手がけています。