Blog
It's a Wonderful Life
根据一个文件的路径来计算另一个文件的相对路径
这是另一道在PHP面试的时候经常考到的题目,解决思路也比较直接。
首先将两个路径都破开成为数组,然后对比相同的部分,这里有个需要注意的点:找相同部分的时候不能使用array_intersect
,因为类似
$path1 = '/home/web/lib/img/cache.php';
$path2 = '/home/web/api/img/show.php';
这样的路径就会解析错误,因为array_intersect
会把两个数组中相同的元素全部提取出来,导致后面我们根据路径有多少相同部分来添加..
定位符的时候就会出BUG。
代码如下:
<?php
/**
* calculate relative path from $from to $to, both need to be absolute path
* @param $from string from path
* @param $to string to path
* @return string relative path to $to
*/
function getRelativePath($from, $to){
$fromArr = explode(DIRECTORY_SEPARATOR, $from);
//remove file's basename
array_shift($fromArr);
//remove the first empty element
array_pop($fromArr);
$toArr = explode(DIRECTORY_SEPARATOR, $to);
array_shift($toArr);
$inter = [];
for ($i = 0; $i < count($fromArr); $i++)
{
if ($fromArr[$i] === $toArr[$i])
{
array_push($inter, $fromArr[$i]);
}
else
{
break;
}
}
$diff = array_diff($fromArr, $inter);
//$from and $to are in same directory
if (! $diff)
{
$prefix = ['.'];
}
else
//how many same parts that these files path contain, we add that many '..' locator
{
$prefix = array_fill(0, count($diff), '..');
}
$toArr = array_slice($toArr, count($inter));
$relativeTo = array_merge($prefix, $toArr);
$relativeTo = implode(DIRECTORY_SEPARATOR, $relativeTo);
return $relativeTo;
}