PHP Warning: include() Failed to open stream: No such file or directoryの修正方法

beginner🐘 PHP2026-03-26| PHP 7.x / 8.x(Linux・Apache/Nginx、Windows・XAMPP/WAMP、macOS)

Error Message

Warning: include(config.php): Failed to open stream: No such file or directory in /var/www/html/index.php on line 3
#php#include#require#ファイルパス#ストリーム

何が起きたのか

この警告が表示された場合 — おそらく白紙ページやアプリの破損も伴っているでしょう — PHPが指定されたファイルを見つけられなかったことが原因です:

Warning: include(config.php): Failed to open stream: No such file or directory in /var/www/html/index.php on line 3

PHPはconfig.phpをディスク上の実際のファイルとして解決できませんでした。十中八九、次の3つのいずれかが問題です:指定したパスにファイルが存在しない、カレントワーキングディレクトリが想定と異なる、またはパス自体にタイポや誤りがある。

デバッグの手順

ステップ1:PHPが実際に探しているパスを確認する

警告には渡した引数しか表示されず、PHPが実際に開こうとした完全な解決済みパスは表示されません。includeの上にデバッグ用のコードを追加して、実際に何が起きているかを確認しましょう:

<?php
echo __DIR__ . '/' . 'config.php' . PHP_EOL;
include('config.php');

またはrealpath()を使ってファイルが存在するかどうかを確認します:

<?php
$path = __DIR__ . '/config.php';
var_dump(file_exists($path), $path);

これを実行し、出力結果をディスク上の実際のファイルと比較してください。

ステップ2:カレントワーキングディレクトリを確認する

include('config.php')のような相対パスは、includeを含むファイルからではなく、**カレントワーキングディレクトリ(CWD)**を基準に解決されます。この2つはしばしば異なります。別のディレクトリからスクリプトを呼び出す場合、フレームワークのフロントコントローラーを使う場合、またはCLIから実行する場合にこの罠にはまりがちです。

<?php
echo getcwd(); // カレントワーキングディレクトリを出力

/var/www/htmlを期待していたのに/var/wwwが返ってきた場合、それが原因です。

ステップ3:ファイルが実際に存在するかを確認する

# Linux/macOSの場合
ls -la /var/www/html/config.php

# タイポを探す — Linuxは大文字小文字を区別する
find /var/www/html -name "config*"

LinuxではConfig.phpconfig.phpは別々のファイルです。WindowsはNot case-sensitiveなので、XAMPP上では問題なく動くタイポが、Linuxサーバーにプッシュした途端に破綻します。

解決策

修正1:信頼性の高い相対パスに__DIR__を使う(推奨)

ほとんどのケースはこれで解決します。__DIR__は、PHPが呼び出された場所ではなく、現在のファイルのディレクトリに解決されるマジック定数です。

<?php
// BEFORE(脆弱 — CWDが変わると壊れる)
include('config.php');
include('../lib/helpers.php');

// AFTER(信頼性が高い — 常にこのファイルからの相対パス)
include(__DIR__ . '/config.php');
include(__DIR__ . '/../lib/helpers.php');

プロジェクト内のすべての裸の相対include/requireを__DIR__を使うように変更してください。この一つの変更で、includeパスに関するバグの大半をなくすことができます。

修正2:重要なファイルにはincludeではなくrequireを使う

config.phpが不可欠な場合 — データベース認証情報、アプリ設定、アプリが欠かすことのできないもの — includeの代わりにrequireまたはrequire_onceを使いましょう。

重要な違い:includeはWarningを出力して処理を続行します。requireはFatal Errorをスローして即座に停止します。設定ファイルが欠けたまま静かに処理を続けると、ほぼ必ず20行後に追跡困難な2つ目のエラーが発生します。

<?php
// config.phpが存在しない場合、即座に実行を停止する
require __DIR__ . '/config.php';

修正3:実際のファイルパスを確認して修正する

CWDは正しいが、ファイルが別の場所にある場合はパスを修正します:

<?php
// ファイルの場所: /var/www/html/includes/config.php
// スクリプトの場所: /var/www/html/index.php

// 間違い
include('config.php');

// 正しい
include __DIR__ . '/includes/config.php';

修正4:ファイルが本当に存在しない場合 — 作成する

最もシンプルな説明が正しいこともあります。新規チェックアウト時には.gitignoreによってconfig.phpが除外されていることがよくあります。テンプレートを探してみましょう:

# サンプル設定ファイルを確認
ls /var/www/html/config.php.example
ls /var/www/html/config.example.php

# コピーして値を入力する
cp config.php.example config.php
nano config.php

修正5:ファイルのパーミッション(あまり多くないが実際にある)

ファイルは存在するがPHPが開けない場合:

# 所有者とパーミッションを確認する
ls -la /var/www/html/config.php

# PHPは通常www-dataとして実行される — 読み取りアクセスを付与する
chown www-data:www-data /var/www/html/config.php
chmod 644 /var/www/html/config.php

ここに落とし穴があります:PHPはファイルが存在しない場合パーミッションが拒否された場合の両方で「No such file or directory」と報告します。ファイルが確実に存在するのに警告が続く場合は、次にパーミッションを確認してください。

修正6:include_pathの問題

古いコードベースの中には、PHPのinclude_path設定(php.iniまたはset_include_path()で設定)に依存しているものがあります。現在の設定を確認するには:

<?php
// 現在のinclude_pathを確認する
echo get_include_path();

// ディレクトリを追加する
set_include_path(get_include_path() . PATH_SEPARATOR . '/var/www/html/includes');
include 'config.php'; // PHPはincludes/も検索するようになる

ただし、自分のアプリケーションファイルにinclude_pathを頼るのはやめましょう — 脆弱です。明示的な__DIR__パスを使い、include_pathはライブラリやオートロードの設定に限定してください。

確認

修正を適用した後、デバッグコードを削除する前に実際に動作することを確認しましょう:

<?php
$file = __DIR__ . '/config.php';
if (!file_exists($file)) {
    die('File not found: ' . $file);
}
if (!is_readable($file)) {
    die('File not readable: ' . $file);
}
require $file;
echo 'Config loaded OK';

「Config loaded OK」と表示されたら、デバッグ用のコードを削除します。そしてPHPエラーログを確認して警告が消えていることを確認しましょう:

# Apache
tail -f /var/log/apache2/error.log

# Nginx + PHP-FPM
tail -f /var/log/php8.x-fpm.log

# またはphp.iniのerror_logが指している場所

クイックリファレンス:includeとrequireの違い

  • include — 失敗時にWarningを出力し、実行を継続する
  • require — 失敗時にFatal Errorをスローし、実行を停止する
  • include_once / require_once — 同じ動作だが、すでにインクルード済みの場合はスキップする

設定ファイル、データベース接続、または重要な処理には常にrequireを使いましょう。includeはオプションのテンプレート断片に限定してください。

教訓

根本的な混乱はほぼ常に同じです:PHPが呼び出された場所includeを含むファイルが存在する場所は同じではありません。__DIR__を使いましょう。毎回。例外なく。

require 'something.php'の代わりにrequire __DIR__ . '/something.php'と書けば、この警告を二度と見ることはなくなります。

裸の相対includeだらけのコードベースを引き継いだ場合は、このgrepコマンドでクリーンアップの全体像を把握できます:

grep -rn "include\|require" /var/www/html --include="*.php" | grep -v "__DIR__" | grep -v "vendor/"

その出力の各行は、いつ発生してもおかしくないパスバグの候補です。

Related Error Notes