PHPのinclude関数の使い方!パスを動的に取得する方法。

PHP

他の人がコーディングしたデータを更新することってありますよね。
特に会社員のコーダーは、更新案件って比較的多いのではないでしょうか。

私も日々更新案件を担当しているのですが、htmlではなくPHPファイルで記述されたデータがあります。
PHPは、include関数を使用して、パーツやメタ情報の共通化ができるので便利です。
私も新規で作成するときは、phpを使用します。

ただ、そんなphpですが、ディレクトリ構成をよく考えて作成しないと、面倒なことになります。

今回は、私が遭遇した事案を例にPHPのinclude関数について、備忘録を残していこうと思います。

  • include関数
  • パスの種類
  • パスを取得する関数と定数

この記事では、上記を中心に記述していきます。

include関数とは。

include関数は、外部ファイルを読み込むさいに使用します。
Web制作の場面では、共通化して使いまわしたい記述に対して、ファイルを分ける(外部ファイル)ことで、必要なページで読み込むだけで使用できます。

以下のような部分が共通化しておくと便利です。

  • header
  • footer
  • metaタグ

これだけではありませんが、主に上記3つはTOPページだけでなく、下層ページまで使用することがあるので、分けておくとコーディング時間の削減や、コードの可読性が上がるので便利です。

include関数の使い方。

include関数は、以下のように使用します。

<?php include('パス'); ?>

パスは、相対パス・絶対パスどちらでも構いません。

パスは、「”」で囲ってください。

以下に補足としてパスの種類も記載しておきます。

パスの種類説明
絶対パスhttpから始まるパス
相対パスパスを記述するファイルから見たパス
フルパスサーバー上のパス

requireでもファイルを読み込むことができる。includeとの違い。

include以外にも、「require」という関数を使用しても、外部ファイルを読み込むことができます。

includeとrequireの違いは、以下のようになります。

関数違い
includeエラーが発生しても、その後の処理を続ける。
requireエラーが発生したら、その後の処理を止める。

今回発生した事案。

さて、ここからが本題です。
今回、別の人がコーディングして、既に公開されているサイトを私が更新することになりました。

更新に必要なコーディングデータをダウンロードして、勤務先のサーバーへテストUPしたところ・・・

CSSと画像が、表示されない!!!(その他もろもろエラーが出ている。)

原因は調べるまでもなく、CSSなどのパスずれです。

パスずれを起こす原因。

パスずれを起こす原因は、コードを見たらすぐにわかりました。

それは、ディレクトリ構成の違いでした。

テストサイトと本サイトの違いは、以下の通り。

サイトディレクトリ構成
テストサイトpublic_html / テストサイト用のディレクトリ / サイトデータ
本番サイトpublic_html / サイトデータ

と、いった感じで、社内のテストサイトはデータを1つのディレクトリにまとめて、その配下に多様なデータが配置されている。といったもの。

その点、本番サイトは直下にサイトデータがあります。

この違いによって、PHPのinclude関数で取得したパスがずれてしまい、表示が崩れてしまっていました。

パスを動的に取得してみる。

現在の取得されているパスはルートディレクトリのみを取得しているので、取得するには静的な記述で補足しなくてはなりません。
ですが、静的な記述で補足してしまうと、本番サイトに移行したときに全てのパスがずれてしまい、デザインが崩れてしまいます。

つまり、テストサイトも本番サイトのどちらもパスは動的に取得する必要があります。

動的にパスを取得できるPHPの関数を調べて試す。

関数を調べて使用する前に、Webデータのディレクトリ構成を明確にしておきます。

index.php
∟各ページのindex.php
∟assetes
    ∟css
       ∟style.css
    ∟img
       ∟各ページごとの画像データ
    ∟inc
       ∟common
          ∟各パーツごとに分けられたphpファイル
    ∟js
       ∟script.js

主要な部分を書き出すと上記のような構成になっています。
ここで重要なのが「/inc/comon」の中に読み込み用のphpファイルが格納されているということです。

incの中には、head内で読み込むようなメタデータやCSS、jsファイルの読み込み記述も入っているため、incからデータを読み込めないとサイトが崩れてしまいます。

現状のパスを調べてみる。

現状のパスと、使用されている関数は以下の通りです。

<?php include(ROOT . '/assets/inc/common/head.php'); ?>

//出力されるパス
/ルートディレクトリ/

つまり、サーバーで設定したルートディレクトリまでしか動的にパスを取得してくれません。
そのため、本番サイトでは’/assets/inc/common/head.php’でファイルを拾えるのですが・・・
テストサイトでは、「public_html / テストサイト用のディレクトリ / サイトデータ」となっているので、パスずれします。

冒頭でもお話ししたように、既存のコードに「テストサイト用のディレクトリ」を追記すればテストサイトでは問題なく表示されますが、本番サイトに移行した時は逆に崩れてしまいます。

そのため、テストサイトでも本番サイトでも動的にパスを取得する必要がでてきます。

phpで動的にパスを取得する関数。

以下、動的にパスを取得できる関数です。
もっとありますが、今回は私が調べて検証に使用した関数のみ記載しておきます。

関数取得できるパス
$_SERVER[‘DOCUMENT_ROOt];ドキュメントルート
__DIR__実行されたphpのディレクトリ名
dirname(__FILE__)実行されたphpのディレクトリ名
dirname(__DIR__)ドキュメントルート

以上が、パスを動的に取得できる関数です。
もっと他の関数を知りたい方は、下記のサイトが詳しく解説してくれています。
私も参考にさせていただきました!

Qiita

PHPのパス、ファイルの取得方法の調査。_SERVERから取得できるディレクトリパス。「_E……

検証した結果。

それぞれ解説していきたいとこですが・・・「$_SERVER[‘DOCUMENT_ROOt];」と「dirname(__DIR__)」は、検証するまでもなく、「<?php include(ROOT . ‘/assets/inc/common/head.php’); ?>」の記述と同じ結果になります。よって、残す2つを検証してみました。

ですが、どちらも「実行されたphpのディレクトリ名」を取得してくるので、今回でいうと以下のようになります。

/ルートディレクトリ/inc/common/

となってしまいます。

確かにincの中だけであれば、ファイルをすべて取得できるのですが、CSSやimgは取得できません。深いディレクトリまで入りすぎています。
commonがなく、incの中にphpファイルが入ってるのであれば、これで解決!全て拾うことができたのですが・・・commonまではいってしまうと、上の階層まで戻らなくては取得することができません。

検証した結果を受けてどうしたか。

以上のような結果になり、どうしたのか。というと・・・結局サブドメインを作成して、そのルートディレクトリ直下にデータを配置して更新の作業をしました。

これであれば、サーバーのディレクトリ構成は同じなため(テストサイトも本番サイトも)、どちらでも問題なく表示されます。

動的にパスを取得することも重要だが、ディレクトリの構成も重要!

今回学んだことで、ディレクトリ構成の大切さを理解しました。
適当にディレクトリを作成して、ファイルを格納していると、今回のようにphpの関数でパスを的確に拾うことができず、せっかく使いまわせるパーツも使いまわせなくなってしまいます。

あとは、phpはサーバーサイド言語のため、サーバー環境を同じにしてあげることも重要なのだと学びました。
そもそも、今回のようなこともサーバー側の環境が同じであればパスのことを気にするともなく、すぐに作業に入れるので、やはりテストサイトはサイトごとサブドメインを取得して、ルートディレクトリ直下にデータを格納してあげることが重要ですね。