Как получить относительный каталог независимо от того, где он входит в PHP?

Если он Path_To_DocumentRoot/a/b/c.php, всегда должен быть /a/b.

Я использую это:

dirname($_SERVER["PHP_SELF"])

Но он не будет работать, если он будет включен другим файлом в другой каталог.

ИЗМЕНИТЬ

Мне нужен относительный путь к документу root. Он используется в веб-приложении.

Я нахожу, что есть еще один вопрос с той же проблемой, но пока не принято ответа.

PHP - преобразовать путь к файловой системе для URL

Ответ 1

У вас есть доступ к $_SERVER['SCRIPT_NAME']? Если вы это сделаете, выполните:

dirname($_SERVER['SCRIPT_NAME']);

Должен работать. В противном случае выполните следующее:

В PHP < 5.3:

substr(dirname(__FILE__), strlen($_SERVER['DOCUMENT_ROOT']));

Или PHP >= 5.3:

substr(__DIR__, strlen($_SERVER['DOCUMENT_ROOT']));

Вам может потребоваться realpath() и str_replace() all \ до /, чтобы сделать его полностью переносимым, например:

substr(str_replace('\\', '/', realpath(dirname(__FILE__))), strlen(str_replace('\\', '/', realpath($_SERVER['DOCUMENT_ROOT']))));

Ответ 2

PHP < 5.3:

dirname(__FILE__)

PHP >= 5.3:

__DIR__

EDIT:

Вот код, чтобы получить путь к включенному файлу относительно пути запуска php файла:

    $thispath = explode('\\', str_replace('/','\\', dirname(__FILE__)));
    $rootpath = explode('\\', str_replace('/','\\', dirname($_SERVER["SCRIPT_FILENAME"])));
    $relpath = array();
    $dotted = 0;
    for ($i = 0; $i < count($rootpath); $i++) {
        if ($i >= count($thispath)) {
            $dotted++;
        }
        elseif ($thispath[$i] != $rootpath[$i]) {
            $relpath[] = $thispath[$i]; 
            $dotted++;
        }
    }
    print str_repeat('../', $dotted) . implode('/', array_merge($relpath, array_slice($thispath, count($rootpath))));

Ответ 3

Мне нужно было создать что-то, что вам нужно, вот результат. Предоставляя базовый каталог, вы получаете относительный путь к файлу, начиная с базового каталога. Функция довольно быстро, 100 000 чеков взяли 0,64 с. на моем сервере. И он работает как для каталогов, так и для файлов. Это совместимо с linux. Даже не пробуйте его на окнах:)

     /**
     * Return a relative path to a file or directory using base directory. 
     * When you set $base to /website and $path to /website/store/library.php
     * this function will return /store/library.php
     * 
     * Remember: All paths have to start from "/" or "\" this is not Windows compatible.
     * 
     * @param   String   $base   A base path used to construct relative path. For example /website
     * @param   String   $path   A full path to file or directory used to construct relative path. For example /website/store/library.php
     * 
     * @return  String
     */
    function getRelativePath($base, $path) {
        // Detect directory separator
        $separator = substr($base, 0, 1);
        $base = array_slice(explode($separator, rtrim($base,$separator)),1);
        $path = array_slice(explode($separator, rtrim($path,$separator)),1);

        return $separator.implode($separator, array_slice($path, count($base)));
    }

Использование

Вам нужно получить относительный путь к файлу /var/www/example.com/media/test.jpg Ваш базовый путь /var/www/example.com

Используйте следующую функцию:

$relative = getRelativePath('/var/www/example.com','/var/www/example.com/media/test.jpg');

Функция вернет /media/test.jpg.

Если вам нужна только часть /media без использования файла, выполните следующие действия:

$relative = dirname(getRelativePath('/var/www/example.com','/var/www/example.com/media/test.jpg'));

Ответ 4

Я знаю, что это старый вопрос, но решения, предлагаемые с помощью DOCUMENT_ROOT, предполагают, что структура веб-папок отражает структуру папок сервера. У меня есть ситуация, когда это не так. Мое решение таково. Вы можете определить, как адрес сервера сопоставляется с веб-адресом, если у вас есть пример из тех же папок с отображенными областями. Пока корневой файл php, содержащий этот файл, находится в одной и той же отображаемой области, у вас есть пример.

$_ SERVER ['SCRIPT_FILENAME'] - адрес сервера этого файла, а $_SERVER ['PHP_SELF'] - это веб-относительная версия. Учитывая эти два варианта, вы можете определить, что веб-относительная версия вашего файла со своего адреса сервера (__FILE__) выглядит следующим образом.

function getCurrentFileUrl() {
    $file = __FILE__;
    $script = $_SERVER['SCRIPT_FILENAME'];
    $phpself = $_SERVER['PHP_SELF'];

    // find end of section of $file which is common to $script
    $i = 0;
    while($file[$i] == $script[$i]) {
        $i++;
    }
    // remove end section of $phpself that is the equivalent to the section of $script not included in $file. 
    $phpself = substr($phpself, 0, strlen($phpself)-(strlen($script)-$i));
    // append end section of $file onto result
    $phpself .= substr($file, $i, strlen($file)-$i);

    // complete address 
    return $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['SERVER_NAME'].$phpself;
}