最初に実行されたスクリプトの絶対パスを取得する


247

私は高低を検索して、絶対パスを取得するための情報を含む多くの異なるソリューションと変数を取得しました。しかし、それらはある条件下では機能し、他の状況では機能しないようです。PHPで実行されたスクリプトの絶対パスを取得するための特効薬はありますか?私にとって、スクリプトはコマンドラインから実行されますが、Apacheなどで実行された場合でもソリューションは機能するはずです。

明確化:最初に実行されたスクリプト。必ずしもソリューションがコーディングされているファイルではありません。


確かに真のmathheadinclouds。私はスクリプトを1つだけ持っていて、それが私のために働いたずっと前にそれを受け入れました。受け入れられた回答を削除して、最初の問題を解決しないことを明確にしました。スクリプトで実行が開始されたときにFILE定数を格納することは1つの方法ですが、理想とはほど遠いものです。
2014年

要求されたスクリプトはあなたが望んだものであり、現在のスクリプト=このソリューションコードを使用
Bitterblue

回答:


33

正しい解決策は、get_included_files関数を使用することです。

list($scriptPath) = get_included_files();

これにより、次の場合でも初期スクリプトの絶対パスが得られます。

  • この関数はインクルードファイル内に配置されます
  • 現在の作業ディレクトリは初期スクリプトのディレクトリとは異なります
  • スクリプトは、相対パスとしてCLIで実行されます

以下は2つのテストスクリプトです。メインスクリプトとインクルードファイル:

# C:\Users\Redacted\Desktop\main.php
include __DIR__ . DIRECTORY_SEPARATOR . 'include.php';
echoScriptPath();

# C:\Users\Redacted\Desktop\include.php
function echoScriptPath() {
    list($scriptPath) = get_included_files();
    echo 'The script being executed is ' . $scriptPath;
}

そしてその結果; 現在のディレクトリに注意してください:

C:\>php C:\Users\Redacted\Desktop\main.php
The script being executed is C:\Users\Redacted\Desktop\main.php

このソリューションは機能しますが、ドキュメントを読んで、最初に実行されたスクリプトのパスがによって返される配列の最初の項目であることは言及されていませんget_included_files()。私が提案する店に__FILE__最初に実行されることを意味し、スクリプトの先頭で定数に。
Paolo、

270

__FILE__ 定数は、現在のファイルへの絶対パスを提供します。

更新

現在実行中のスクリプトではなく、最初に実行されたスクリプトを取得する方法を尋ねる質問が変更されました。これを行う唯一の(??)信頼できる方法は、debug_backtrace関数を使用することです。

$stack = debug_backtrace();
$firstFrame = $stack[count($stack) - 1];
$initialFile = $firstFrame['file'];

フロントコントローラーパターンを使用している場合。思い__FILE__のindex.phpの場所やインクルードファイルの場所を返しますか?index.phpの場所を取得するにはどうすればよいですか?
CMCDragonkai 2013年

まあ__FILE__、現在のスクリプトのパスを指します。しかし、現在のindex.phpのパスを示すものは何も見つかりませんでした。
CMCDragonkai 2013年

1
@CMCDragonkai:別の質問をしてから
zerkms

2
注意:スクリプトがapache2仮想ディレクトリにある場合、返される情報は物理サーバー上の実際のパスの場所を提供しません。私はこれをデバッグ目的で使用したかったのですが、$ _ SERVER変数でさえ提供されていません。たとえば、index.phpが/ var / www / vpath1 / htmlと/ var / www / html /と/ var / www / vpath2 / htmlに存在し、これらのそれぞれが/ var / www / htmlに仮想的にマッピングされている場合、その場合、使用されている仮想サーバーに関係なく、/ var / www / htmlが表示されます。
マークリチャーズ

1
@ChristofferBubachをスローする必要すらありません。例外オブジェクトは、構築中にスタックトレースを収集します。
zerkms 2018

262

回答はここに移動されました-https://stackoverflow.com/a/26944636/2377343


1
スクリプトの現在のフォルダーを取得するには str_replace( basename(__FILE__) , '',str_replace($_SERVER["DOCUMENT_ROOT"],'',str_replace('\\','/',__FILE__ ) ) ) === /folder1/folder2/
セーラム

2
これは、インターネット全体で見たファイルパスの一部またはすべてを取得する方法の例の中で、これまでで最も包括的なリストです。
Sean the Bean

241
echo realpath(dirname(__FILE__));

これをインクルードファイルに配置すると、このインクルードへのパスが出力されます。親スクリプトのパスを取得するには、交換してください__FILE__$_SERVER['PHP_SELF']。ただし、PHP_SELFはセキュリティリスクであることに注意してください。


1
これはまさに私が欲しかったものでした
11

13
ここでリアルパスの用途は何ですか?
常識

11
@Col。Shrapnel:「PHP 4.0.2以降、__FILE__常にシンボリックリンクが解決された絶対パスが含まれていましたが、古いバージョンでは、状況によっては相対パスが含まれていました。」プラス「DIRNAME()は、入力文字列に単純に動作し、実際のファイルシステムを認識しない、または例えば『..』パスコンポーネント。
RIK

6
ああ、4.0.2。前世紀?
常識

2
@rik:また、どのようなセキュリティ問題が発生する可能性がありますPHP_SELFか?
zerkms

38
__DIR__

マニュアルから

ファイルのディレクトリ。インクルード内で使用すると、インクルードされたファイルのディレクトリが返されます。これはと同等dirname(__FILE__)です。このディレクトリ名は、ルートディレクトリでない限り、末尾にスラッシュがありません。
__FILE__ シンボリックリンクが解決された絶対パスが常に含まれているのに対し、古いバージョン(4.0.2以降)では、状況によっては相対パスが含まれていました。

__DIR__PHP 5.3.0で追加されました。



8
dirname(__FILE__) 

絶対ルートを与える あなたがルートを求めている、そこから現在のファイルの、サーバーのディレクトリのルートを。

サンプルファイル:

www / http / html / index.php; このコードをindex.php内に配置すると、次のコードが返されます。

<?php echo dirname(__FILE__); // this will return: www/http/html/

www / http / html / class / myclass.php; このコードをmyclass.php内に配置すると、次のコードが返されます。

<?php echo dirname(__FILE__); // this will return: www/http/html/class/


7

以下を使用してください:

echo __DIR__;

1
申し訳ありませんが、アイデアは最初に起動されたスクリプトを取得することです...あなたがたまたま入ったスクリプトではありません。だから、の包含ツリーはa.php->b.php->c.phpのパスでなければなりませんa.phpでチェック場合c.php。信頼できると思われる唯一の方法は、debug_backtrace()関数を使用することです。
2015年

5
`realpath(dirname(__FILE__))` 

末尾のスラッシュなしで現在のスクリプト(このコードを配置したスクリプト)のディレクトリを提供します。結果に他のファイルを含めたい場合、これは重要です


そうですが、アイデアは、「発火スクリプト」A.phpへの絶対パスをB.php内に含めても、それがA.phpに含まれていれば取得できるようにすることです。最初のスクリプトを保存して後でアクセスできるようにすることもできますが、それを行わずにそれを取得できるかどうかが問題でした。
2015

4

サーバーのルートからの絶対パスを探している場合、これがうまく機能することがわかりました。

$_SERVER['DOCUMENT_ROOT'] . dirname($_SERVER['SCRIPT_NAME'])

別のサーバーに対してこのソリューションをチェックしていたとき、ホストのOS(WindowsおよびLinux)に関係なく、dirセパレーターのようなlinuxのパスが常に与えられました。私にとってそれは利点です。
Bronek 16

3

これは私がこれを正確に記述した便利なPHP関数です。元の質問で明らかになったように、最初のスクリプトが実行されたパスが返されます。現在のファイルではありません。

/**
 * Get the file path/dir from which a script/function was initially executed
 * 
 * @param bool $include_filename include/exclude filename in the return string
 * @return string
 */ 
function get_function_origin_path($include_filename = true) {
    $bt = debug_backtrace();
    array_shift($bt);
    if ( array_key_exists(0, $bt) && array_key_exists('file', $bt[0]) ) {
        $file_path = $bt[0]['file'];
        if ( $include_filename === false ) {
            $file_path = str_replace(basename($file_path), '', $file_path);
        }
    } else {
        $file_path = null;
    }
    return $file_path;
}


1
realpath($_SERVER['SCRIPT_FILENAME'])

Webサーバーで実行さ$_SERVER['SCRIPT_FILENAME']れるスクリプトの場合、最初に呼び出されたスクリプトへの完全なパスが含まれるため、おそらくindex.phpになります。realpath()この場合、必要ありません。

コンソールから実行さ$_SERVER['SCRIPT_FILENAME']れたスクリプトには、現在の作業ディレクトリから最初に呼び出されたスクリプトへの相対パスが含まれます。したがって、スクリプト内の作業ディレクトリを変更しない限り、絶対パスに解決されます。


1

これは私が使用するもので、Linux環境で機能します。これはWindowsマシンでは機能しないと思います...

//define canonicalized absolute pathname for the script
if(substr($_SERVER['SCRIPT_NAME'],0,1) == DIRECTORY_SEPARATOR) {
    //does the script name start with the directory separator?
    //if so, the path is defined from root; may have symbolic references so still use realpath()
    $script = realpath($_SERVER['SCRIPT_NAME']);
} else {
    //otherwise prefix script name with the current working directory
    //and use realpath() to resolve symbolic references
    $script = realpath(getcwd() . DIRECTORY_SEPARATOR . $_SERVER['SCRIPT_NAME']);
}

1

絶対パスを持っている簡単な方法最初に実行されるスクリプトは、そのスクリプト内に含まれている任意の他のスクリプトincluderequirerequire_once使用することである定数との初めに存在現在のスクリプトのパスを格納するメインスクリプト

define( 'SCRIPT_ROOT', __FILE__ );

上記のソリューションは、単一の「メイン」スクリプトが存在する場合に適しています。 include、ほとんどのWebアプリケーションのように、他のすべての必要なスクリプトでます。

そうでない場合、いくつかの「初期スクリプト」が存在する可能性がある場合、再定義を回避し、定数内に正しいパスを格納するには、各スクリプトを次のように開始します。

if( ! defined( 'SCRIPT_ROOT' ) ) {
    define( 'SCRIPT_ROOT`, __FILE__ );
}

(現在)受け入れられている回答に関するメモ

答えは、最初に実行されたスクリプトのパスがによって返される配列の最初の要素であると述べています get_included_files()ます。

これは巧妙でシンプルなソリューションであり、-執筆時点では-(ほぼPHP 7.4.0です)機能します。

ただし、ドキュメントを見ると、最初に実行されたスクリプトがによって返される配列の最初の項目であることについては言及されていませんget_included_files()

読むだけ

最初に呼び出されたスクリプトは「インクルードファイル」と見なされるため、インクルードおよびファミリによって参照されるファイルとともにリストされます。

執筆時点では、「最初に呼び出されたスクリプト」は配列の最初のスクリプトですが、技術的には、これが将来変更されないという保証はありません。


注意realpath()__FILE____DIR__

他の人がその答えでの使用を示唆しています__FILE____DIR__dirname(__FILE__)realpath(__DIR__)...

dirname(__FILE__)__DIR__(PHP 5.3.0で導入された)と等しいため、を使用してください__DIR__

両方__FILE____DIR__常に絶対パスのでrealpath()不要です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.