How to get the relative directory no matter from where it's included in PHP?

Viewed 47183

If it's Path_To_DocumentRoot/a/b/c.php,should always be /a/b.

I use this:

dirname($_SERVER["PHP_SELF"])

But it won't work when it's included by another file in a different directory.

EDIT

I need a relative path to document root .It's used in web application.

I find there is another question with the same problem,but no accepted answer yet.

PHP - Convert File system path to URL

5 Answers

Do you have access to $_SERVER['SCRIPT_NAME']? If you do, doing:

dirname($_SERVER['SCRIPT_NAME']);

Should work. Otherwise do this:

In PHP < 5.3:

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

Or PHP >= 5.3:

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

You might need to realpath() and str_replace() all \ to / to make it fully portable, like this:

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

PHP < 5.3:

dirname(__FILE__)

PHP >= 5.3:

__DIR__

EDIT:

Here is the code to get path of included file relative to the path of running php file:

    $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))));

Here's a general purpose function to get the relative path between two paths.

/**
 * Return relative path between two sources
 * @param $from
 * @param $to
 * @param string $separator
 * @return string
 */
function relativePath($from, $to, $separator = DIRECTORY_SEPARATOR)
{
    $from   = str_replace(array('/', '\\'), $separator, $from);
    $to     = str_replace(array('/', '\\'), $separator, $to);

    $arFrom = explode($separator, rtrim($from, $separator));
    $arTo = explode($separator, rtrim($to, $separator));
    while(count($arFrom) && count($arTo) && ($arFrom[0] == $arTo[0]))
    {
        array_shift($arFrom);
        array_shift($arTo);
    }

    return str_pad("", count($arFrom) * 3, '..'.$separator).implode($separator, $arTo);
}

Examples

relativePath('c:\temp\foo\bar', 'c:\temp');              // Result: ../../
relativePath('c:\temp\foo\bar', 'c:\\');                 // Result: ../../../
relativePath('c:\temp\foo\bar', 'c:\temp\foo\bar\lala'); // Result: lala
Related