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


110

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


私の意見では受け入れられた回答よりも正確です:stackoverflow.com/a/23902890/1636522

回答:


132

これは、メインスクリプト(この場合はA.php)を基準にしています。include()現在実行中のスクリプトにコードを挿入するだけです。

つまり、インクルードがどのファイルから呼び出されるかは重要ですか

番号。

あなたがしたい場合は作る事を、そしてB.phpに対する含ま行い、使用__FILE__定数を(または__DIR__PHP 5.2 IIRC以降)リテラル現在のファイルを常にポイントコードの行が置かれているということ。

include(dirname(__FILE__)."/C.PHP");

@ Pekka-すごい-まさに私が探していたもの。詳細については、stackoverflow.com
questions / 2184810 /

7
__DIR__その正確な目的にも使用できます。
Nick Bedford

1
この答えはやややりすぎです:必要ないinclude(dirname(__FILE__)."/C.PHP");のでinclude("C.PHP");、十分です(はい!C.PHPはB.PHPと同じディレクトリに置くことができます)プロジェクトに2つのC.PHPファイルがある場合のみ失敗する可能性があります。
ジョニーウォン

より明確にするために:インクルードパスに "./"または "../"プレフィックスがない場合は、B.phpとA.phpの両方に相対的です。以下の私の答えを参照してください。
ジョニーウォン

21

@ペッカは私をそこに連れて行きましたが、私が学んだことを共有したいだけです:

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__)を使用する理由


何かを追加したいのですが、csb.phpというファイルがあり、フォルダーからの機能ファイルが含まれています。機能ファイルには、機能ファイルと同じフォルダーのt.phpという名前のファイルが含まれています。 t.phpフォルダーのcsb.phpという名前のファイルには、関数ファイルを呼び出したのと同じcsb.phpが含まれ始めましたが、2番目のcsb.phpをcsbe.phpに変更すると、すぐに機能し始めました。したがって、最初のフォルダーを優先し、次に2番目のインクルードフォルダーを優先するように見えます。
ミゲルビエイラ

17
  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()。)


結論として、最初にA.phpのパスでC.phpが検索され、次にインクルードに接頭辞「./」または「../」がない場合はB.phpのパスが検索されます。(デフォルトのPHP設定を想定)
Johnny Wong

を使用chdir(__DIR__)して問題を解決してくれてありがとう。
HartleySan 2016年

[...] getcwd()、デフォルトはエントリ.phpファイルのパスです[...] -必ずしもtrueであるとは限りません。コマンドラインでPHPを実行する場合getcwd()、どの.phpファイルを呼び出すかに関係なく、シェルの現在の作業ディレクトリを参照します。ただし、PHPがWebサーバー環境で実行されている場合、環境が現在の作業ディレクトリをエントリ.phpファイルに初期化することは想像できます。Homebrewを介してインストールされたPHP 7.2.2を備えたmacOSでテストされています。
herzbube

16

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

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

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

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

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


「これが失敗するとdirname(__FILE__) (__DIR__)、php> = 5.3を使用して、呼び出し元のスクリプトの独自のディレクトリを検索します。」どこに記載されていますか?私はあなたが間違っている願って、そしてPHPはないではない使用__FILE__して__DIR__のために、この目的は、そのよう速やかから「兄弟」スクリプトを含む破るシンボリックリンクのもの!:-o(幸いなことに、ここでは7.1の設定で問題なく動作するようです。)
Sz。

6

短い答え:インクルードするスクリプトに関連します。

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

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

あれば、/app/main.phpは言うinclude("./inc.php")ことがわかります/app/inc.php

./は必須ではありませんが、include_pathの上の任意の依存関係を削除します。

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


文字列を./で開始する場合、最初に呼び出し元のスクリプトのディレクトリまたは現在の作業ディレクトリを確認しますか?
Pacerier、2015年

2
@Denis Howeいいえ、インクルードパスがで始まる場合は、すでに現在の作業ディレクトリに依存しています./。つまり、chdir( "/ app / other")はinclude("./inc.php")失敗します。したがって、include("inc.php")この場合は安全に使用してください。
ジョニー・ウォン

@Pacerierは、文字列が./または../で始まる場合、現在の作業ディレクトリのみをチェックします。(include_pathと呼び出しスクリプトのディレクトリ(B.php)はどちらも無視されます)。詳細については、私の回答を参照してください。
ジョニー・ウォン

-2
dir
-> a.php
-> c.php

- dir2 
-> b.php

含めるにabあなたがする必要がinclude("../a.php");

含めるにbcあなたがする必要がinclude("dir2/b.php");


4
@ Olli-質問の要点を逃しています-インクルードがチェーンされているときに相対パスがどのように決定されるかについて尋ねていました。
Yarin
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.