public static function getRelativePath(string $from, string $to): string
    {
        $from = self::getUnixStylePath($from);
        $to = self::getUnixStylePath($to);
        if (is_dir($from)) {
            $from = self::getNormalizedPath($from);
        }
        if (is_dir($to)) {
            $to = self::getNormalizedPath($to);
        }

        $from = explode('/', $from);
        $to = explode('/', $to);
        $relativePath = $to;

        foreach ($from as $depth => $directory) {
            // find first non-matching dir
            if ($directory === $to[$depth]) {
                // ignore this directory
                array_shift($relativePath);
            } else {
                // get number of remaining dirs to $from
                $remaining = count($from) - $depth;
                if ($remaining > 1) {
                    // add traversals up to first matching dir
                    $padLength = (count($relativePath) + $remaining - 1) * -1;
                    $relativePath = array_pad($relativePath, $padLength, '..');
                    break;
                }
                $relativePath[0] = './' . $relativePath[0];
            }
        }
        return implode('/', $relativePath);
    }
public static function getRelativePath(string $from, string $to): string
    {
        $from = self::getUnixStylePath($from);
        $to = self::getUnixStylePath($to);
        if (is_dir($from)) {
            $from = self::getNormalizedPath($from);
        }
        if (is_dir($to)) {
            $to = self::getNormalizedPath($to);
        }

        $from = explode('/', $from);
        $to = explode('/', $to);
        $relativePath = $to;

        foreach ($from as $depth => $directory) {
            // find first non-matching dir
            if ($directory === $to[$depth]) {
                // ignore this directory
                array_shift($relativePath);
            } else {
                // get number of remaining dirs to $from
                $remaining = count($from) - $depth;
                if ($remaining > 1) {
                    // add traversals up to first matching dir
                    $padLength = (count($relativePath) + $remaining - 1) * -1;
                    $relativePath = array_pad($relativePath, $padLength, '..');
                    break;
                }
                $relativePath[0] = './' . $relativePath[0];
            }
        }
        return implode('/', $relativePath);
    }
public static function getRelativePath ( string $ from , string $ to ) : string { $ from = self :: getUnixStylePath ( $ from ) ; $ to = self :: getUnixStylePath ( $ to ) ; if ( is_dir ( $ from ) ) { $ from = self :: getNormalizedPath ( $ from ) ; } if ( is_dir ( $ to ) ) { $ to = self :: getNormalizedPath ( $ to ) ; } $ from = explode ( '/' , $ from ) ; $ to = explode ( '/' , $ to ) ; $ relativePath = $ to ; foreach ( $ from as $ depth => $ directory ) { // find first non-matching dir if ( $ directory === $ to [ $ depth ] ) { // ignore this directory array_shift ( $ relativePath ) ; } else { // get number of remaining dirs to $from $ remaining = count ( $ from ) - $ depth ; if ( $ remaining > 1 ) { // add traversals up to first matching dir $ padLength = ( count ( $ relativePath ) + $ remaining - 1 ) * - 1 ; $ relativePath = array_pad ( $ relativePath , $ padLength , '..' ) ; break ; } $ relativePath [ 0 ] = './' . $ relativePath [ 0 ] ; } } return implode ( '/' , $ relativePath ) ; }
Finds the relative path between two given absolute paths.
Credits go to stackoverflow member "Gordon".

@see http://stackoverflow.com/questions/2637945/

@param string $from An absolute path to base on
@param string $to An absolute path to find the relative representation onto $from
@return string
Finds the relative path between two given absolute paths . Credits go to stackoverflow member Gordon .