Получить абсолютный путь текущего script

Я искал максимум и минимум и получал много разных решений и переменных, содержащих информацию, чтобы получить абсолютный путь. Но они, кажется, работают в одних условиях, а не в других. Есть ли один способ "серебряной пули" получить абсолютный путь к исполняемому скрипту в PHP? Для меня сценарий будет запускаться из командной строки, но решение должно работать так же хорошо, если оно выполняется в Apache и т.д.

Уточнение. Первоначально выполняемый скрипт, а не обязательно файл, в котором закодировано решение.

Ответ 1

Правильное решение - использовать функцию get_included_files:

list($scriptPath) = get_included_files();

Это даст вам абсолютный путь к исходному сценарию, даже если:

  • Эта функция находится внутри включенного файла
  • Текущий рабочий каталог отличается от исходного каталога скриптов
  • Сценарий выполняется с CLI, как относительный путь

Вот два тестовых сценария; основной скрипт и включенный файл:

# 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

Ответ 2

__FILE__ даст вам абсолютный путь к текущему файлу.

Обновление:

Вопрос был изменен, чтобы спросить, как получить первоначально выполненный сценарий вместо текущего запущенного сценария. Единственный (??) надежный способ сделать это - использовать функцию debug_backtrace.

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

Ответ 3

Примеры для: https://(www.)example.com/subFolder/yourfile.php?var=blabla#555

//=================================================== 
//========== 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                            //like: $_SERVER["SERVER_PROTOCOL"] 
$_SERVER['HTTP_HOST']      🡺       example.com                //like: $_SERVER["SERVER_NAME"]
$_SERVER["REQUEST_URI"]    🡺                       /subFolder/yourfile.php?var=blabla
$_SERVER["QUERY_STRING"]   🡺                                               var=blabla
__FILE__                   🡺 /home/user/public_html/subFolder/yourfile.php
__DIR__                    🡺 /home/user/public_html/subFolder      //like: dirname(__FILE__)
$_SERVER["REQUEST_URI"]    🡺                       /subFolder/yourfile.php?var=blabla
parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH)🡺  /subFolder/yourfile.php 
$_SERVER["PHP_SELF"]       🡺                       /subFolder/yourfile.php

// ==================================================================
//if "YOURFILE.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/yourfile.php




// ===================================================
// ============== PARSE_URL & PATHINFO ==============
// ===================================================
//parse_url
$x = parse_url($url);
$x['scheme']               🡺 https
$x['host']                 🡺       example.com
$x['path']                 🡺                  /subFolder/yourfile.php
$x['query']                🡺                                          var=blabla
$x['fragment']             🡺                                                     555 // hashtag outputed only in case, when hashtag-containing string was manually passed to function, otherwise PHP is unable to recognise hashtags in $_SERVER

//pathinfo (If you will ever use this function, I only recommend to pass 'parse_url output as argument)
A = pathinfo($url);
B = pathinfo(parse_url($url)['path']);
A['dirname']               🡺 https://example.com/subFolder
B['dirname']               🡺                    /subFolder
A['basename']              🡺                               yourfile.php?var=blabla#555
B['basename']              🡺                               yourfile.php
A['extension']             🡺                                        php?var=blabla#555
B['extension']             🡺                                        php
A['filename']              🡺                               yourfile
B['filename']              🡺                               yourfile





// ===================================================
// ================= 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)             🡺 yourfile.php

//excellent solution to find origin
$debug_files = debug_backtrace();       
$caller_file = count($debug_files) ? $debug_files[count($debug_files) - 1]['file'] : __FILE__;

Обратите внимание !:

  • хэштег (#...) части URL не могут быть обнаружены в PHP (на стороне сервера). Для этого используйте JavaScript.
  • DIRECTORY_SEPARATOR возвращает \ для хостинга типа Windows вместо /.



Для WordPress

//(let 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/  

Ответ 4

echo realpath(dirname(__FILE__));

Если вы разместите его во включенном файле, он напечатает путь к этому включению. Чтобы получить путь к родительскому script, замените __FILE__ на $_SERVER['PHP_SELF']. Но имейте в виду, что PHP_SELF - это риск для безопасности!

Ответ 5

__DIR__

Из руководства:

Каталог файла. Если используется внутри включения, возвращается каталог включенного файла. Это эквивалентно dirname(__FILE__). Это имя каталога не имеет косой черты, если только оно не является корневым каталогом.
__FILE__ всегда содержит абсолютный путь с разрешенными символическими __FILE__ тогда как в более старых версиях (чем 4.0.2) он содержал относительный путь при некоторых обстоятельствах.

Примечание: __DIR__ был добавлен в PHP 5.3.0.

Ответ 6

Если вы хотите получить текущий рабочий каталог, используйте getcwd()

http://php.net/manual/en/function.getcwd.php

__FILE__ вернет путь с именем файла, например, в XAMPP C:\xampp\htdocs\index.php вместо C:\xampp\htdocs\

Ответ 7

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/

Ответ 8

Просто используйте ниже:

echo __DIR__;

Ответ 9

Если вы ищете абсолютный путь относительно корня сервера, я обнаружил, что это хорошо работает:

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

Ответ 10

`realpath(dirname(__FILE__))` 

он предоставляет вам текущий script (script, внутри которого вы поместили этот код) каталог без конечной косой черты. это важно, если вы хотите включить другие файлы с результатом

Ответ 11

В случае использования фреймворка большинство из них не работает, поэтому я нашел решение для этого. Код:

echo dirname(__FILE__).'\\'.basename(__FILE__);

Он должен указывать абсолютный путь, включая имя файла.

Ответ 12

Здесь полезная функция PHP, которую я написал для этого точно. По мере выяснения исходного вопроса он возвращает путь, из которого был выполнен начальный script, а не файл, в котором мы сейчас находимся.

/**
 * 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;
}

Ответ 13

realpath($_SERVER['SCRIPT_FILENAME'])

Для script запустите под веб-сервером $_SERVER['SCRIPT_FILENAME'] будет содержать полный путь к изначально называемому script, поэтому, вероятно, ваш index.php. realpath() в этом случае не требуется.

Для запуска script с консоли $_SERVER['SCRIPT_FILENAME'] будет относительный путь к вашему изначально названному script из вашего текущего рабочего каталога. Поэтому, если вы не изменили рабочий каталог внутри вашего script, он решит абсолютный путь.

Ответ 14

попробуйте это на script

echo getcwd() . "\n";

Ответ 15

Самый простой способ получить абсолютный путь к изначально выполненному сценарию из этого "основного" сценария и любого сценария, включенного в include, require, require_once - это сохранить его в константе в начале основного сценария:

define( 'SCRIPT_ROOT', __FILE__ );

__FILE__ возвращает путь к текущему сценарию. Используемый внутри включенного скрипта возвращает путь включенного файла, а не сценарий, который изначально запускается, когда запрос OP:

Пояснение: начальный исполняемый скрипт, а не файл, в котором мы сейчас находимся

Решение сохранения __FILE__ в константу проще и быстрее, чем извлечение пути с помощью debug_backtrace()


Приведенное выше решение подходит, когда есть один "основной" сценарий, который include все остальные необходимые сценарии, как в большинстве веб-приложений.

Если это не так и может существовать несколько "жизненных сценариев", то во избежание переопределений и сохранения правильного пути внутри константы каждый сценарий может начинаться с:

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

Ответ 16

Это то, что я использую, и это работает в среде 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']);
}