奇妙な状況に遭遇したとき、私はPHPでWebアプリを書いていました。私の問題を説明するために、この構造のWebアプリを考えてみましょう。
/
index.php
f1/
f1.php
f2/
f2.php
これらのファイルの内容:
index.php:
<?php require_once("f1/f1.php"); ?>
f1.php:
<?php require_once("../f2/f2.php"); ?>
f2.php:空白
ブラウザでindex.phpを開こうとすると、次のエラーが発生します。
Warning: require_once(../f2/f2.php) [function.require-once]:
failed to open stream: No such file or directory in /var/www/reqtest/f1/f1.php on line 2
Fatal error: require_once() [function.require]:
Failed opening required '../f2/f2.php' (include_path='.:/usr/share/php:/usr/share/pear') in /var/www/reqtest/f1/f1.php on line 2
私が見逃している明らかなものはありますか?インクルードパスはPHPでどのように機能しますか?
この質問をする前に、私は実験して調べようとしました。次のように、別のテストを設定しました。
/
index.php
f1/
f1.php
f2.php
index.php:
<?php require_once("f1/f1.php"); ?>
f1.php:
<?php require_once("f2.php"); ?>
f2.php:空白
驚いたことに(そしてまったく混乱して)、これはうまくいきました!
では、パス解決の背後にある秘密は何ですか?
PS私が見た この質問 、しかしそれは私がここで述べた2番目のケースにまだ答えていません。
別のファイルをインクルードすると、作業ディレクトリはインクルードファイルがある場所に残ります。
あなたの例は意図したとおりに機能しています。
編集: 2番目の例は。 (実際のディレクトリ)はインクルードパスにあります(エラーメッセージを参照してください)。
Edit2: 2番目の例では、関心のある重要なポイントは次の行です。
<?php require_once("f2.php"); ?>
最初は、現在の作業ディレクトリ(/var/www/req_path_test
)が、f2.phpが見つかりません。
フォールバックとして、include_pathでf2.phpを見つけようとします('.:/usr/share/php:/usr/share/pear'
)、 で始まります '。' (これは実際のファイルに関連しており、含むファイルではありません)。
したがって、「。/f2.php」は機能し、requireは失敗しません。
Index.phpを開くと、作業ディレクトリはこのファイルが存在するフォルダーに設定されます。また、含まれているf1.php内では、この作業ディレクトリは変更されません。
次のように、現在含まれているファイルを基準にして、絶対パスを使用してファイルを含めることができます。
require_once(dirname(__FILE__).'/../../test/file.php')
ただし、これらのファイルにクラスが含まれている場合は、オートローダーの使用を検討することをお勧めします。
PHPドキュメント PHPインクルード から
ファイルは、指定されたファイルパスに基づいてインクルードされます。指定されていない場合は、include_pathが指定されます。ファイルがinclude_pathに見つからない場合、includeは、失敗する前に、呼び出し元のスクリプト自体のディレクトリと現在の作業ディレクトリを最終的にチェックインします。
ファイルパスが指定されていない場合、つまりrequire_once( "f2.php");
1日include_pathがチェックされます
2位。呼び出し元のスクリプト自身のディレクトリがチェックされます
3位。最後に、現在の作業ディレクトリがチェックされます
ファイルが見つからない場合PHPファイルインクルードに警告をスローし、requireに致命的なエラーをスローします
パスが定義されている場合(絶対(Windowsではドライブ文字または\で始まる、Unix/Linuxシステムでは/で始まる)、または現在のディレクトリからの相対パス(。または..で始まる))、include_pathは完全に無視されます。たとえば、ファイル名が../で始まる場合、パーサーは親ディレクトリを調べて、要求されたファイルを見つけます。
で始まるファイルを含める/必要とする場合。または..または./次に、PHPのパーサーは、現在の作業ディレクトリである親ディレクトリ、つまりrequire_once( "../ f2/f2.php")を検索し、phpは呼び出し元のスクリプトindex.phpとしてルートディレクトリをチェックします。そのディレクトリにあります。
これで、PHPスクリプトにインクルードパスが定義されていないため、常に呼び出し元のスクリプトにフォールバックしてから、現在の作業ディレクトリにフォールバックします。
// Check your default include path, most likely to be C:\xampp\php\PEAR
echo get_include_path();
// To set include path
set_include_path ( string $new_include_path ) : string
現在の作業ディレクトリは、メインの呼び出しスクリプトindex.phpから派生しています。
// The Current Working Directory can be checked
echo getcwd();
必要なファイル「../f2/f2.php」がf1.phpからのものである最初の例では
あなたのコードは次の理由で機能しません-
したがって、致命的なエラーが発生します
2番目の例では、ディレクトリを変更し、f1.phpからrequire_once( "f2.php")を変更しました。
あなたのコードは次の理由で機能します-
したがって、コードは正常に機能します!
通常あなたの古い構造で
<?php require_once("f2/f2.php"); ?>
の代わりに
<?php require_once("../f2/f2.php"); ?>
動作するはずです。私の知る限り、phpは最初のスクリプトからパスを取ります
サーバーのPHP構成で open_basedir 設定が有効になっているようです。これにより、ディレクトリ構造内の上のフォルダにファイルを含める(および開く)ことができなくなります。 (つまり、.. /を使用してフォルダー構造を上に移動することはできません)。