Search code examples
phprelative-path

Getting relative path from absolute path in PHP


I noticed some similar questions about this problem when I typed the title, but they seem not be in PHP. So what's the solution to it with a PHP function?

To be specified.

$a="/home/apache/a/a.php";
$b="/home/root/b/b.php";
$relpath = getRelativePath($a,$b); //needed function,should return '../../root/b/b.php'

Any good ideas? Thanks.


Solution

  • Try this one:

    function getRelativePath($from, $to)
    {
        // some compatibility fixes for Windows paths
        $from = is_dir($from) ? rtrim($from, '\/') . '/' : $from;
        $to   = is_dir($to)   ? rtrim($to, '\/') . '/'   : $to;
        $from = str_replace('\\', '/', $from);
        $to   = str_replace('\\', '/', $to);
    
        $from     = explode('/', $from);
        $to       = explode('/', $to);
        $relPath  = $to;
    
        foreach($from as $depth => $dir) {
            // find first non-matching dir
            if($dir === $to[$depth]) {
                // ignore this directory
                array_shift($relPath);
            } else {
                // get number of remaining dirs to $from
                $remaining = count($from) - $depth;
                if($remaining > 1) {
                    // add traversals up to first matching dir
                    $padLength = (count($relPath) + $remaining - 1) * -1;
                    $relPath = array_pad($relPath, $padLength, '..');
                    break;
                } else {
                    $relPath[0] = './' . $relPath[0];
                }
            }
        }
        return implode('/', $relPath);
    }
    

    This will give

    $a="/home/a.php";
    $b="/home/root/b/b.php";
    echo getRelativePath($a,$b), PHP_EOL;  // ./root/b/b.php
    

    and

    $a="/home/apache/a/a.php";
    $b="/home/root/b/b.php";
    echo getRelativePath($a,$b), PHP_EOL; // ../../root/b/b.php
    

    and

    $a="/home/root/a/a.php";
    $b="/home/apache/htdocs/b/en/b.php";
    echo getRelativePath($a,$b), PHP_EOL; // ../../apache/htdocs/b/en/b.php
    

    and

    $a="/home/apache/htdocs/b/en/b.php";
    $b="/home/root/a/a.php";
    echo getRelativePath($a,$b), PHP_EOL; // ../../../../root/a/a.php