私は高値と安値を検索し、絶対パスを取得するための情報を含むさまざまな解決策と変数を多数取得しています。しかし、それらはある条件下では機能し、他の条件下では機能しないようです。 PHPで実行されたスクリプトの絶対パスを取得するための簡単な方法はありますか?私にとっては、スクリプトはコマンドラインから実行されますが、Apacheなどの中で実行された場合でも、ソリューションは同様に機能するはずです。
説明:最初に実行されたスクリプト。必ずしもソリューションがコーディングされているファイルではありません。
正しい解決策は get_included_files
関数を使うことです。
list($scriptPath) = get_included_files();
次のような場合でも、初期スクリプトの絶対パスがわかります。
これが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
__FILE__
定数は現在のファイルへの絶対パスを与えます。
更新 :
現在実行中のスクリプトの代わりに最初に実行されたスクリプトを取得する方法を尋ねるために質問が変更されました。そのための唯一の(??) 信頼できる 方法は debug_backtrace
関数を使うことです。
$stack = debug_backtrace();
$firstFrame = $stack[count($stack) - 1];
$initialFile = $firstFrame['file'];
https://(www.)example.com/subFolder/myfile.php?var=blabla#555
の例
// ======= PATHINFO ====== //
$x = pathinfo($url);
$x['dirname'] ???? https://example.com/subFolder
$x['basename'] ???? myfile.php?
$x['extension'] ???? php?k=blaa#12345 // Unsecure! also, read my notice about hashtag parts
$x['filename'] ???? myfile
// ======= PARSE_URL ====== //
$x = parse_url($url);
$x['scheme'] ???? https
$x['Host'] ???? example.com
$x['path'] ???? /subFolder/myfile.php
$x['query'] ???? k=blaa
$x['fragment'] ???? 12345 // ! read my notice about hashtag parts
//=================================================== //
//========== self-defined SERVER variables ========== //
//=================================================== //
$_SERVER["DOCUMENT_ROOT"] ???? /home/user/public_html
$_SERVER["SERVER_ADDR"] ???? 143.34.112.23
$_SERVER["SERVER_PORT"] ???? 80(or 443 etc..)
$_SERVER["REQUEST_SCHEME"] ???? https //similar: $_SERVER["SERVER_PROTOCOL"]
$_SERVER['HTTP_Host'] ???? example.com (or with WWW) //similar: $_SERVER["ERVER_NAME"]
$_SERVER["REQUEST_URI"] ???? /subFolder/myfile.php?k=blaa
$_SERVER["QUERY_STRING"] ???? k=blaa
__FILE__ ???? /home/user/public_html/subFolder/myfile.php
__DIR__ ???? /home/user/public_html/subFolder //same: dirname(__FILE__)
$_SERVER["REQUEST_URI"] ???? /subFolder/myfile.php?k=blaa
parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH)???? /subFolder/myfile.php
$_SERVER["PHP_SELF"] ???? /subFolder/myfile.php
// ==================================================================//
//if "myfile.php" is included in "PARENTFILE.php" , and you visit "PARENTFILE.PHP?abc":
$_SERVER["SCRIPT_FILENAME"]???? /home/user/public_html/parentfile.php
$_SERVER["PHP_SELF"] ???? /parentfile.php
$_SERVER["REQUEST_URI"] ???? /parentfile.php?abc
__FILE__ ???? /home/user/public_html/subFolder/myfile.php
// =================================================== //
// ================= handy variables ================= //
// =================================================== //
//If site uses HTTPS:
$HTTP_or_HTTPS = ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS']!=='off') || $_SERVER['SERVER_PORT']==443) ? 'https://':'http://' ); //in some cases, you need to add this condition too: if ('https'==$_SERVER['HTTP_X_FORWARDED_PROTO']) ...
//To trim values to filename, i.e.
basename($url) ???? myfile.php
//excellent solution to find Origin
$debug_files = debug_backtrace();
$caller_file = count($debug_files) ? $debug_files[count($debug_files) - 1]['file'] : __FILE__;
通知!:
DIRECTORY_SEPARATOR
は、\
の代わりに、Windowsタイプのホスティングに対して/
を返します。//(let's say, if wordpress is installed in subdirectory: http://example.com/wpdir/)
home_url() ???? http://example.com/wpdir/ //if is_ssl() is true, then it will be "https"
get_stylesheet_directory_uri() ???? http://example.com/wpdir/wp-content/themes/THEME_NAME [same: get_bloginfo('template_url') ]
get_stylesheet_directory() ???? /home/user/public_html/wpdir/wp-content/themes/THEME_NAME
plugin_dir_url(__FILE__) ???? http://example.com/wpdir/wp-content/themes/PLUGIN_NAME
plugin_dir_path(__FILE__) ???? /home/user/public_html/wpdir/wp-content/plugins/PLUGIN_NAME/
echo realpath(dirname(__FILE__));
これをインクルードファイルに入れると、このインクルードへのパスが表示されます。親スクリプトのパスを取得するには、__FILE__
を$_SERVER['PHP_SELF']
に置き換えます。しかし、PHP_SELFはセキュリティ上のリスクがあることに注意してください。
__DIR__
から マニュアル :
ファイルのディレクトリインクルード内で使用されている場合は、インクルードファイルのディレクトリが返されます。これはdirname(__FILE__)
と同等です。このディレクトリ名は、ルートディレクトリでない限り末尾にスラッシュを付けません。
__FILE__
シンボリックリンクが解決された絶対パスを常に含みますが、旧バージョン(4.0.2より前)では、状況によっては相対パスを含んでいました。
注 :PHP 5.3.0に__DIR__
が追加されました。
現在の作業ディレクトリを取得したい場合 use getcwd()
http://php.net/manual/en/function.getcwd.php
__FILE__
は、たとえばXAMPPのC:\xampp\htdocs\index.php
ではなくC:\xampp\htdocs\
上でファイル名のパスを返します
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/
以下を使用してください。
echo __DIR__;
サーバールートからの絶対パスを探しているなら、これがうまくいくことがわかりました。
$_SERVER['DOCUMENT_ROOT'] . dirname($_SERVER['SCRIPT_NAME'])
`realpath(dirname(__FILE__))`
末尾にスラッシュを付けずに、現在のスクリプト(このコードを配置したスクリプトの)ディレクトリになります。結果に他のファイルを含めたい場合、これは重要です。
これが私が正確に書いた便利なPHP関数です。元の質問が明確にしているように、それは initial スクリプトが実行されたパスを返します。
/**
* 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;
}
これは私が使っているもので、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']);
}
realpath($_SERVER['SCRIPT_FILENAME'])
Webサーバーで実行されるスクリプトの場合、$_SERVER['SCRIPT_FILENAME']
には最初に呼び出されたスクリプトへのフルパスが含まれます。おそらくあなたのindex.phpになります。この場合、realpath()
は必要ありません。
コンソールから実行されるスクリプトの場合、$_SERVER['SCRIPT_FILENAME']
には、現在作業中のディレクトリから最初に呼び出されたスクリプトへの相対パスが含まれます。スクリプト内の作業ディレクトリを変更しない限り、絶対パスになります。
あなたのスクリプトでこれを試してください
echo getcwd() . "\n";
最初に実行されたスクリプトの絶対パスをその「メイン」スクリプトとinclude
、require
、require_once
に含まれるスクリプトから取得する最も簡単な方法は、メインスクリプトの先頭にある定数に格納することです。
define( 'SCRIPT_ROOT', __FILE__ );
__FILE__
は現在のスクリプトのパスを返します。インクルードスクリプト内で使用すると、 インクルードファイルのパス が返されます。OPが最初に実行したときに実行されるスクリプトではありません。
説明:最初に実行したスクリプトで、現在入っているファイルではありません
__FILE__
を定数に格納する解決策は、debug_backtrace()
を使用してパスを取得するよりも簡単かつ迅速です。
上記の解決策は、ほとんどのWebアプリケーションのように、必要なスクリプトを1つおきにinclude
する単一の「メイン」スクリプトがある場合に適しています。
そうではなく、いくつかの "intital scripts"がある場合は、再定義を避け、正しいパスを定数内に格納するようにします。各スクリプトは次のようになります。
if( ! defined( 'SCRIPT_ROOT' ) ) {
define( 'SCRIPT_ROOT`, __FILE__ );
}