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

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

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

16 ответов


правильным решением является использование 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

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

обновление:

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


echo realpath(dirname(__FILE__));

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


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

типичные коды PHP:

//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`s 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


//=================================================== 
//========== 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

// ===================================================
// ================= 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();       $initial_called_file = count($debug_files) ? $debug_files[count($debug_files) - 1]['file'] : __FILE__;

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

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



Для WordPress

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

__DIR__

С руководство:

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

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


если вы хотите получить текущий рабочий каталог использовать 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 ; если вы разместите этот код внутри своего индекса.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__))` 

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


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

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

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


вот полезная функция 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;
}

попробуйте это на ваш скрипт

echo getcwd() . "\n";

realpath($_SERVER['SCRIPT_FILENAME'])

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

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


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

define( 'SCRIPT_ROOT', __FILE__ );

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

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

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


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

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

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

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