PHPでファイルを分割してメンテナンスしやすくする方法を紹介します。
またrequire、include、require_once、function_existsの使い方を紹介します。
先に結論をまとめます。requireはファイルが無いと致命的エラーで停止し、includeは警告を出して処理を続けます。require_onceは同じファイルを何度書いても1回しか読み込まないため、関数やクラスを定義したファイルの読み込みに向きます。どれも関数ではなくPHPの言語構造なので、require 'file.php';のように括弧なしで書けます。
ファイルの構成
∟file1.php
∟file2.php
∟index.php
上のようなファイル構成で、
file1.phpとfile2.phpの中身を、index.phpから使えるようにします。
file1.phpの記述
<?php
// 関数がすでに宣言されていない場合
if(!function_exists('func1')) {
function func1() {
echo 'func1が呼ばれた';
}
}
file2.phpの記述
file2が読み込まれた。
file2.phpにはPHPのコードを書かず、表示したいテキスト(HTML)だけを置いています。読み込まれるとその内容がそのまま出力されます。
index.phpの記述
<?php
// 使いたいファイルを読み込む
require('file1.php');
require 'file1.php';
// 関数を実行する
func1();
//func1が呼ばれた
// file2を読み込む
require('file2.php');
//file2が読み込まれた。
まずは、使いたいファイルをrequire()を使って読み込みます。
requireは()で囲んでもキーワードとして指定してもOKです。
パスは、index.phpを実行しているディレクトリではなく、実行時のカレントディレクトリとinclude_pathを基準に解決されます。別の場所から呼ばれても壊れないように、実務ではrequire __DIR__ . '/file1.php';と書くのが安全です。詳しくはPHPのパス指定と__DIR__・__FILE__の使い方を参照してください。
これはファイルを読み込んだだけのため、
そのファイルの中の使いたい関数を実行します。
phpファイルではhtmlでもいいので、読み込んだファイルにHTMLがあればそれが表示されます。
function_exists()でエラーを防ぐ
<?php
// function_exists()でエラーを防ぐ
if(!function_exists('func')) {
function func() {
// 関数の処理
}
}
require()を何度も実行すると、読み込んだファイルの関数がグローバルスコープに何度も宣言されることになり、エラーになります。
そこで、function_exists()を使って、宣言されていない場合のみその関数を宣言するようにします。
PHPのファイルのスコープについて
PHPにはファイルごとのスコープがありません。
そのため、require()で読み込んだ場合、index.phpのグローバルスコープに関数が配置されます。
つまり同じ名前の関数を作成しようとするとエラーが出ますので注意が必要です。
スコープについては、【PHP】グローバルスコープ、ローカルスコープ、スーパーグローバルについて を参照してみてください。
require、require_onceの使い方
require()では、実行するたびに何度でも該当のファイルを読み込みます。
require_once()では、何度実行しても該当のファイルを一度だけ読み込みます。
同じファイルをrequireやincludeで先に読み込んでいた場合も、require_onceはそれを「読み込み済み」と判断して再読み込みしません。includeにも同じ動きをするinclude_onceがあります。
<?php
// requireの例
require('file2.php');
require('file2.php');
require('file2.php');
//file2が読み込まれた。
//file2が読み込まれた。
//file2が読み込まれた。
// require_onceの例
require_once('file2.php');
require_once('file2.php');
require_once('file2.php');
//file2が読み込まれた。
require、includeの違い
require()とinclude()は、ファイルが見つからなかったときに挙動の違いがでてきます。
require()の場合、もしファイルが見つからない場合は、致命的なエラーと認識され、それ以降の処理が止まります。
それに対し、include()の場合は、警告レベルのエラーと認識され、ファイルがない場合でもそれ以降の処理が実行されます。
そのため、絶対に必要なファイルはrequire()で読み込み、無くても処理を続けてよいファイルはinclude()で読み込む、という使い分けをします。
関数を書いたファイルは無いと致命的なので、require()(定義の重複を避けるならrequire_once())を使います。HTMLだけのパーツはinclude()で十分です。
ローカルで動作確認するには
ここまでのコードは、PHPが動くローカルサーバーで確認します。VS Codeの拡張機能PHP Serverで「PHP Not Found」と出て動かない場合は、VS Code「PHP Not Found」の直し方でphpPathの設定を確認してください。