需求:給定兩個絕對路徑 $a、$b,求 $b 相對於 $a 的相對路徑。例:/a/b/c/d/e.php 對 /a/b/12/34/c.php → ../../12/34/c.php。
/ 分割路徑為陣列$a 到共同祖先需幾個 ../$b 的剩餘路徑function getRelativePath($from, $to) {
$from = rtrim($from, '/');
$to = rtrim($to, '/');
$fromParts = explode('/', $from);
$toParts = explode('/', $to);
// 找共同前綴長度
$common = 0;
$minLen = min(count($fromParts), count($toParts));
for ($i = 0; $i < $minLen; $i++) {
if ($fromParts[$i] === $toParts[$i]) $common++;
else break;
}
// 建構相對路徑
$up = count($fromParts) - $common;
$rel = str_repeat('../', $up);
$rel .= implode('/', array_slice($toParts, $common));
return $rel;
}
// 測試
echo getRelativePath('/a/b/c/d/e.php', '/a/b/12/34/c.php'); // ../../12/34/c.php
echo getRelativePath('/var/www/a.php', '/var/www/b/c.php'); // b/c.php
echo getRelativePath('/a/b/c', '/x/y/z'); // ../../../x/y/z
realpath() 正規化(解析符號連結、..、.)\ 需統一轉 / 或用 DIRECTORY_SEPARATORuse Symfony\Component\String\UnicodeString; $rel = (new UnicodeString($to))->getRelativePath($from);
掌握核心演算法,或直接用成熟元件避免邊界錯誤。