在建立動態連結、資源引用時,常需根據兩個絕對路徑計算相對路徑。以下為可直接使用的函數實作。
<?php
/**
* 計算 $targetPath 相對於 $basePath 的相對路徑
* @param string $basePath 基準路徑(如 /var/www/project/a.js)
* @param string $targetPath 目標路徑(如 /var/www/project/js/b.js)
* @return string 相對路徑(如 ../js/b.js)
*/
function getRelativePath($basePath, $targetPath)
{
// 統一路徑分隔符並移除檔名
$baseDir = rtrim(dirname($basePath), '/') . '/';
$targetDir = rtrim(dirname($targetPath), '/') . '/';
$targetFile = basename($targetPath);
// 分割成陣列
$baseParts = explode('/', $baseDir);
$targetParts = explode('/', $targetDir);
// 找出共同前綴
$commonLen = 0;
while (
isset($baseParts[$commonLen]) &&
isset($targetParts[$commonLen]) &&
$baseParts[$commonLen] === $targetParts[$commonLen]
) {
$commonLen++;
}
// 建構相對路徑:../ 回到共同祖先
$relative = '';
for ($i = $commonLen; $i < count($baseParts); $i++) {
$relative .= '../';
}
// 加上目標路徑剩餘部分
for ($i = $commonLen; $i < count($targetParts); $i++) {
$relative .= $targetParts[$i] . '/';
}
return $relative . $targetFile;
}
// 使用範例
$file1 = 'aaa/ddd/ccc/ddd/test/a.js';
$file2 = 'aaa/ddd/ccc/ddd/test/b.js';
echo getRelativePath($file1, $file2); // 輸出:b.js(同目錄)
$file3 = 'aaa/bbb/ccc/d.php';
$file4 = 'aaa/eee/fff/g.php';
echo getRelativePath($file3, $file4); // 輸出:../../eee/fff/g.php
?>
src、href、CSS url() 等。專案中建議封裝為工具類,並加入單元測試覆蓋邊界情況(根目錄、同檔名不同目錄、含符號連結等)。