include / include_once / require / require_once
外部ファイルを読み込んで処理を共有するには『include』『include_once』『require』『require_once』の4つの関数を使います。『PHP』ではこれらを使って設定ファイルやテンプレートを読み込み、コードを複数のファイルに分割して管理できます。
構文
// ファイルを読み込みます(失敗しても処理が続きます)
include 'ファイルパス';
include('ファイルパス');
// ファイルを読み込みます(失敗すると致命的エラーで処理が停止します)
require 'ファイルパス';
require('ファイルパス');
// 同じファイルを2回以上読み込まないようにします(include の重複防止版)
include_once 'ファイルパス';
// 同じファイルを2回以上読み込まないようにします(require の重複防止版)
require_once 'ファイルパス';
4つの関数の違い
| 関数 | 読み込み失敗時の挙動 | 重複読み込み |
|---|---|---|
| include | Warning(警告)を出して処理を続行します。 | そのたびに読み込みます。 |
| include_once | Warning(警告)を出して処理を続行します。 | 2回目以降は無視します。 |
| require | Fatal Error(致命的エラー)で処理を停止します。 | そのたびに読み込みます。 |
| require_once | Fatal Error(致命的エラー)で処理を停止します。 | 2回目以降は無視します。 |
使い分けの指針
| 場面 | 推奨 | 理由 |
|---|---|---|
| 設定ファイル・DB接続ファイルの読み込み | require / require_once | 読み込めなければ以降の処理が成立しないため、即座に停止させるべきです。 |
| 関数・クラス定義ファイルの読み込み | require_once | 同じ関数・クラスが2回定義されるとエラーになるため、重複防止が必要です。 |
| テンプレート(ヘッダー・フッター等)の読み込み | require / include | テンプレートは1回だけ呼ぶ設計が多く、_once は不要なことが多いです。 |
| オプション扱いのパーツ(あってもなくてもよい) | include | 読み込めなくてもサイト全体を止めたくない場合に使います。 |
パスの指定方法
| 指定方法 | 例 | 概要 |
|---|---|---|
| 相対パス | '../config/db.php' | 実行中のスクリプトが置かれているディレクトリからの相対位置で指定します。include_path の影響を受けます。 |
| 絶対パス | '/var/www/html/config/db.php' | ファイルシステムの絶対パスで指定します。どこから実行しても同じファイルを参照できます。 |
| __DIR__ を使った絶対パス | __DIR__ . '/config/db.php' | 現在のファイルが置かれているディレクトリの絶対パスを基準にします。相対パスの曖昧さを排除でき、実用上もっとも安全です。 |
サンプルコード
config.php
<?php
// KOFのキャラクターデータを管理する設定ファイルです
// このファイル単体では何も出力しません
$teamKOF = [
"草薙チーム" => ["草薙京", "二階堂紅丸", "大門五郎"],
"餓狼チーム" => ["テリー・ボガード", "アンディ・ボガード", "東丈"],
"八神チーム" => ["八神庵", "マチュア", "バイス"],
];
$tournament = "THE KING OF FIGHTERS '97";
header_tpl.php
<?php
// ページ共通のヘッダー部分を出力するテンプレートです
// $tournament 変数が渡されていることを前提にしています
?>
<header>
<h1><?= htmlspecialchars($tournament) ?></h1>
</header>
include_basic.php
<?php
// require_once で設定ファイルを読み込みます
// 設定ファイルは必須のため require を使います
// __DIR__ を使うことで、このファイルの場所を基準にパスを解決します
require_once __DIR__ . '/config.php';
// ヘッダーテンプレートを読み込みます
// テンプレートは1回だけ呼ぶため _once なしでも問題ありません
require __DIR__ . '/header_tpl.php';
// 読み込んだ config.php の変数をそのまま使えます
echo $tournament . " 参加チーム一覧:\n\n";
foreach ($teamKOF as $teamName => $members) {
echo "【" . $teamName . "】\n";
foreach ($members as $fighter) {
echo " - " . $fighter . "\n";
}
echo "\n";
}
実行すると次のように出力されます。
php include_basic.php
<header>
<h1>THE KING OF FIGHTERS '97</h1>
</header>
THE KING OF FIGHTERS '97 参加チーム一覧:
【草薙チーム】
- 草薙京
- 二階堂紅丸
- 大門五郎
【餓狼チーム】
- テリー・ボガード
- アンディ・ボガード
- 東丈
【八神チーム】
- 八神庵
- マチュア
- バイス
include_once_demo.php
<?php // require_once の重複防止の動作を確認するサンプルです // 同じファイルを2回 require_once しても、実際の読み込みは1回だけです require_once __DIR__ . '/config.php'; // 2回目の require_once は無視されます($teamKOF の再定義エラーが起きません) require_once __DIR__ . '/config.php'; // $teamKOF は1回だけ定義されています echo "読み込んだ大会名: " . $tournament . "\n"; echo "チーム数: " . count($teamKOF) . "\n";
実行すると次のように出力されます。
php include_once_demo.php 読み込んだ大会名: THE KING OF FIGHTERS '97 チーム数: 3
include_vs_require.php
<?php // include と require の失敗時の挙動の違いを確認するサンプルです // --- include の場合 --- // 存在しないファイルを include しても Warning が出るだけで処理は続きます echo "include 前\n"; include 'not_found_file.php'; // Warning: include(not_found_file.php): ... echo "include 後(この行は実行されます)\n\n"; // --- require の場合 --- // 存在しないファイルを require すると Fatal Error で処理が止まります echo "require 前\n"; require 'not_found_file.php'; // Fatal error: require(): Failed opening required ... echo "require 後(この行は実行されません)\n"; // ← ここには到達しません
実行すると次のように出力されます。
php include_vs_require.php include 前 Warning: include(not_found_file.php): Failed to open stream: No such file or directory in ... Warning: include(): Failed opening 'not_found_file.php' for inclusion ... include 後(この行は実行されます) require 前 Fatal error: require(): Failed opening required 'not_found_file.php' ...
functions.php
<?php
// KOFの対戦結果を表示するヘルパー関数を定義するファイルです
// クラスや関数を定義するファイルは require_once で読み込みます
// (同じファイルを2回読み込むと「関数の再定義エラー」になるためです)
function formatBattleResult(string $winner, string $loser, string $finisher): string {
return $winner . " が " . $loser . " に " . $finisher . " で勝利!";
}
function getTeamMembers(array $teamKOF, string $teamName): array {
return $teamKOF[$teamName] ?? [];
}
main.php
<?php
// 関数定義ファイルと設定ファイルを require_once で読み込みます
// 関数・設定は必須かつ重複読み込み不可のため require_once が適切です
require_once __DIR__ . '/functions.php';
require_once __DIR__ . '/config.php';
// 別のファイルから functions.php を require_once していても、
// require_once は2回目以降を無視するので関数の再定義エラーになりません
require_once __DIR__ . '/functions.php'; // この行は無視されます
// 読み込んだ関数を使って対戦結果を出力します
echo formatBattleResult("草薙京", "八神庵", "裏百八拾弐式・天叢雲剣") . "\n";
echo formatBattleResult("テリー・ボガード", "二階堂紅丸", "パワーゲイザー") . "\n";
echo "\n";
// 草薙チームのメンバーを取得します
$members = getTeamMembers($teamKOF, "草薙チーム");
echo "草薙チームのメンバー:\n";
foreach ($members as $fighter) {
echo " - " . $fighter . "\n";
}
実行すると次のように出力されます。
php main.php 草薙京 が 八神庵 に 裏百八拾弐式・天叢雲剣 で勝利! テリー・ボガード が 二階堂紅丸 に パワーゲイザー で勝利! 草薙チームのメンバー: - 草薙京 - 二階堂紅丸 - 大門五郎
よくあるミス
よくあるミス1: require忘れでFatal Errorになる
設定ファイルやDB接続ファイルを読み込むときに『include』を使っていると、ファイルが存在しなくてもWarningを出して処理が続きます。後続のコードはその設定変数が存在する前提で動いているため、「変数が未定義」「接続オブジェクトがnull」などのエラーが別の場所で発生し、原因を追いにくくなります。必須ファイルには『require』を使うと、読み込み失敗の時点でFatal Errorが発生し、問題箇所をすぐに特定できます。
ng_include_config.php
<?php // 設定ファイルに include を使うと、ファイルが存在しなくても処理が続く include 'config.php'; // config.php が存在しない場合でも処理が続く // $teamKOF が未定義のままここに到達してしまう echo count($teamKOF) . " チーム\n"; // Warning: Undefined variable $teamKOF
実行すると次のように出力されます。
php ng_include_config.php Warning: include(config.php): Failed to open stream: No such file or directory in ... Warning: include(): Failed opening 'config.php' for inclusion ... Warning: Undefined variable $teamKOF in ... Fatal error: Uncaught TypeError: count(): Argument #1 ($value) must be of type Countable|array, null given in ...
PHP 8 では count(null) が TypeError になります。未定義変数は null として扱われるため、count($teamKOF) が TypeError を引き起こします。
ok_include_config.php
<?php // 必須ファイルには require を使う。読み込み失敗時にその場でFatal Errorが出る require 'config.php'; // ファイルが存在しなければここでFatal Errorが発生する echo count($teamKOF) . " チーム\n";
実行すると次のように出力されます。
php ok_include_config.php Fatal error: require(): Failed opening required 'config.php' ...
よくあるミス2: 相対パスが実行ディレクトリに依存して失敗する
『include』や『require』の相対パスは、PHPスクリプトが置かれているディレクトリではなく、コマンドを実行したカレントディレクトリを基準に解決されます。別のディレクトリからスクリプトを実行すると、同じコードでもファイルが見つからなくなります。『__DIR__』マジック定数は「そのPHPファイルが置かれているディレクトリの絶対パス」を返すため、どこから実行しても常に同じファイルを参照できます。
ng_relative_path.php
<?php // 相対パスはコマンドを実行したディレクトリを基準に解決される require 'config.php'; // /var/www/html から実行すると /var/www/html/config.php を探す
実行すると次のように出力されます。
php /var/www/html/app/ng_relative_path.php Fatal error: require(): Failed opening required 'config.php' ...
ok_relative_path.php
<?php // __DIR__ を使うと、このファイルが置かれているディレクトリを基準にパスが解決される // どのディレクトリから実行しても常に /var/www/html/app/config.php を参照する require __DIR__ . '/config.php';
実行すると次のように出力されます。
php /var/www/html/app/ok_relative_path.php 3 チーム
よくあるミス3: include_onceで読み込んだファイルの変数が見えない
『include_once』は「重複読み込みを防ぐ」機能ですが、「どこからでも変数が使える」わけではありません。読み込んだファイル内で定義した変数のスコープは通常のincludeと同じです。関数の内側でincludeすると、その変数は関数スコープに属し、外からはアクセスできません。また、2回目以降の『include_once』は読み込みをスキップするため、変数が初期化されないケースもあります。
ng_include_once_scope.php
<?php
// config.php の中で $teamKOF を定義している前提
function loadConfig() {
include_once __DIR__ . '/config.php'; // 関数スコープ内で読み込む
// $teamKOF はこの関数スコープ内でのみ有効
}
loadConfig();
// 関数の外からはアクセスできない(グローバルスコープに $teamKOF は存在しない)
echo count($teamKOF) . " チーム\n"; // Warning: Undefined variable $teamKOF
実行すると次のように出力されます。
php ng_include_once_scope.php Warning: Undefined variable $teamKOF in ... Fatal error: Uncaught TypeError: count(): Argument #1 ($value) must be of type Countable|array, null given in ...
PHP 8 では count(null) が TypeError になります。関数スコープ外に変数が見えないため null のまま渡され、TypeError が発生します。
ok_include_once_scope.php
<?php
// グローバルスコープで include_once を実行すると $teamKOF はグローバル変数になる
include_once __DIR__ . '/config.php';
function loadConfig() {
// 関数内からグローバル変数を使うには global 宣言が必要
global $teamKOF;
echo count($teamKOF) . " チーム\n";
}
loadConfig(); // 3 チーム
echo count($teamKOF) . " チーム\n"; // 3 チーム
実行すると次のように出力されます。
php ok_include_once_scope.php 3 チーム 3 チーム
概要
『include』と『require』はどちらも外部ファイルを読み込む命令ですが、読み込みに失敗したときの挙動が異なります。『include』は Warning を出して処理を続けますが、『require』は Fatal Error で処理を即座に停止させます。DBの接続設定や共通関数など、読み込めなければその後の処理が成立しないファイルには『require』が使われます。
『_once』が付いた版は、すでに読み込み済みのファイルを再度読み込もうとしたとき何もしません。関数やクラスを定義するファイルを複数箇所から読み込む場合に威力を発揮します。同じ関数・クラスを2回定義するとエラーになるため、関数・クラス定義ファイルには『require_once』が使われます。
ファイルパスの指定には相対パスより『__DIR__』を使った絶対パスが安全です。相対パスはスクリプトの実行場所によって解決されるパスが変わることがありますが、『__DIR__』はファイル自身の場所を基準にするため、どこから呼び出されても常に同じファイルを参照できます。ファイルの存在確認については『file_exists()』、ファイルの読み書きについては『fopen() / fclose()』を参照してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。