web-dev-qa-db-ja.com

PHPには、ファイルまたは呼び出しコードに関連するパスが含まれていますか?

PHP相対インクルードパスに関するルールセットの理解に問題があります。ファイルA.PHPを実行し、ファイルA.PHPにファイルC.PHPを含むファイルB.PHPが含まれている場合、C.PHPへの相対パスはB.PHPの場所またはAの場所に関連する必要があります.PHP?つまり、どちらがfile includeの呼び出し元であるか、または現在の作業ディレクトリが何であるか、および現在の作業ディレクトリを決定するのは何ですか?

100
Yarin

メインスクリプト、この場合はA.phpに関連しています。 include()は、現在実行中のスクリプトにコードを挿入するだけであることに注意してください。

つまり、インクルードがどのファイルから呼び出されるかは問題になりますか

番号。

makeが重要で、B.phpに関連するインクルードを行う場合は、__FILE__定数(またはPHP 5.2 IIRC以降の__DIR__を使用します。 )は、コード行が置かれている現在のリテラルファイルを常に指します。

include(dirname(__FILE__)."/C.PHP");
120
Pekka 웃

@Pekkaは私をそこに連れてきましたが、私が学んだことを共有したいだけです。

getcwd()は、実行を開始したファイルが存在するディレクトリを返します。

dirname(__FILE__)は、現在実行中のコードを含むファイルのディレクトリを返します。

これらの2つの関数を使用すると、必要なものに関連するインクルードパスをいつでも構築できます。

たとえば、b.phpとc.phpがディレクトリを共有する場合、b.phpは次のようにc.phpを含めることができます。

include(dirname(__FILE__).'/c.php');

b.phpの呼び出し元に関係なく。

実際、これは相対パスを確立するための好ましい方法です。追加のコードにより、ターゲットファイルを見つけるためにPHPがinclude_pathを反復処理する必要がなくなります。

ソース:

getcwd()とdirname(__ FILE__)の違い?どちらを使用すればよいですか?

なぜdirname(FILE)を使用すべきか

20
Yarin
  1. インクルードパスが./または../で始まっていない場合、例:

    include 'C.php'; // precedence: include_path (which include '.' at first),
                     // then path of current `.php` file (i.e. `B.php`), then `.`.
    
  2. インクルードパスが./または../で始まる場合、例:

    include './C.php';  // relative to '.'
    
    include '../C.php'; // also relative to '.'
    

上記の.または..は、getcwd()に対して相対的であり、デフォルトではエントリ.phpファイルのパスになります(つまり、A.php)。

PHP 5.4.3(ビルド日:2012年5月8日00:47:34)でテスト済み。

chdir()getcwd()の出力を変更できることに注意してください。)

16
Johnny Wong

Pekkaの受け入れられた答えは不完全であり、一般的な文脈では誤解を招きます。ファイルが相対パスとして提供されている場合、呼び出された言語構造includeは次の方法でファイルを検索します。

最初に、include_pathで設定できる環境変数ini_setのパスを通過します。これが失敗した場合、呼び出し元のスクリプト自身のディレクトリdirname(__FILE__)(php> = 5.3で__DIR__)を検索します。これも失敗した場合は、作業ディレクトリのみを検索します!デフォルトでは、環境変数include_pathは現在の作業ディレクトリである.で始まることがわかりました。それが現在の作業ディレクトリで最初に検索する唯一の理由です。 http://php.net/manual/en/function.include.php を参照してください。

ファイルは、指定されたファイルパスに基づいてインクルードされます。指定されていない場合は、include_pathが指定されます。ファイルがinclude_pathで見つからない場合、includeは失敗する前に呼び出しスクリプトの自身のディレクトリと現在の作業ディレクトリを最終的にチェックインします。

したがって、質問の最初の部分に対する正しい答えは、含まれている呼び出しスクリプトがどこにあるかは問題ではないということです。質問の最後の部分に対する答えは、Webサーバーコンテキストでのinitial作業ディレクトリが、呼び出されたスクリプトのディレクトリであるということです。これには、PHPによって処理されている間、他のすべてが含まれます。コマンドラインコンテキストでは、最初の作業ディレクトリは、phpがプロンプトで呼び出されたときのものであり、呼び出されたスクリプトが配置されているディレクトリとは限りません。ただし、current作業ディレクトリは、PHP関数chdirを使用して実行時に変更できます。 http://php.net/manual/en/function.chdir.php を参照してください。

この段落は、他の回答にコメントするために追加されます。 include_pathへの依存は堅牢性が低いため、./path__DIR__ . /pathなどの完全なパスを使用することが望ましいと述べた人もいます。作業ディレクトリ.自体に依存することは、変更される可能性があるため、安全ではないと言う人もいます。ただし、環境値に依存する必要がある場合があります。たとえば、include_pathを空に設定すると、現在の作業ディレクトリの前であっても、呼び出しスクリプトのディレクトリが最初に検索される場所になります。コードはすでに外部ソースから定期的に作成および更新されている可能性があり、コードが更新されるたびに接頭辞__DIR__を再挿入する必要はありません。

12
user2066805

簡単な答え:含めるスクリプトに関連しています。

TFM はそれを正しく説明します:

ファイルがinclude_pathに見つからない場合、includeは呼び出しスクリプトのディレクトリと現在の作業ディレクトリをチェックインします。

したがって、/ app/main.phpinclude("./inc.php")と言うと、/ app/incが見つかります。 php

./は必ずしも必要ではありませんが、include_pathへの依存関係を削除します。

誰かがchdir()で変更した場合に、現在の作業ディレクトリでインクルードファイルを見つけることに依存しません。

4
Denis Howe