首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 計算兩個路徑之間的相對路徑函數

     編輯:PHP 綜合知識

需求場景

在構建資源引用、模板引擎、檔案管理器時,常需根據「基準路徑 A」計算「目標路徑 B」相對於 A 的相對路徑(如 ../../target/file.txt)。

通用實現函數

<?php
/**
 * 獲取 $target 相對於 $base 的相對路徑
 * @param string $base   基準路徑(目錄或文件)
 * @param string $target 目標路徑(目錄或文件)
 * @return string 相對路徑,如 ../foo/bar.txt
 */
function getRelativePath($base, $target) {
    // 統一處理為目錄路徑
    $baseDir   = rtrim(dirname($base), '/');
    $targetDir = rtrim(dirname($target), '/');
    
    // 分割路徑段
    $baseParts   = $baseDir   ? explode('/', $baseDir)   : [];
    $targetParts = $targetDir ? explode('/', $targetDir) : [];
    
    // 找到共同前綴長度
    $common = 0;
    $minLen = min(count($baseParts), count($targetParts));
    while ($common < $minLen && $baseParts[$common] === $targetParts[$common]) {
        $common++;
    }
    
    // 構建相對路徑:向上返回 + 向下進入
    $up   = str_repeat('../', count($baseParts) - $common);
    $down = implode('/', array_slice($targetParts, $common));
    
    $relative = $up . $down;
    return $relative ?: '.'; // 同目錄返回 .
}

// 測試
echo getRelativePath('/var/www/a/b/c.php', '/var/www/a/d/e.txt'); // ../d/e.txt
echo getRelativePath('/home/user/project/src/Controller', '/home/user/project/public/assets'); // ../../public/assets
echo getRelativePath('C:/xampp/htdocs/app', 'C:/xampp/htdocs/app'); // .
?>

邏輯圖解

Base:    /var/www/a/b/
Target:  /var/www/a/d/e.txt
Common:  /var/www/a/  (3 segments)
Up:      ../         (b -> a)
Down:    d/e.txt
Result:  ../d/e.txt

進階:支援 URL 與 Windows 路徑

<?php
function getRelativePathUniversal($base, $target, $isUrl = false) {
    $sep = $isUrl ? '/' : DIRECTORY_SEPARATOR;
    
    // 正規化分隔符
    $base   = str_replace(['\\', '/'], $sep, $base);
    $target = str_replace(['\\', '/'], $sep, $target);
    
    // 去除尾部分隔符
    $base   = rtrim($base, $sep);
    $target = rtrim($target, $sep);
    
    // 取目錄部分
    $baseDir   = $isUrl ? dirname($base) : dirname($base);
    $targetDir = $isUrl ? dirname($target) : dirname($target);
    
    // 同邏輯...
    // (省略,核心同上)
    return $relative;
}
?>

內建替代方案

  • realpath() 先解析符號鏈接、相對路徑,再計算。
  • Symfony Symfony\Component\Filesystem\Path::getRelativePath($base, $target) (PHP 8.1+ 核心已內建 path_relative() 提案中)。
  • Laravel Illuminate\Support\Str::relativePath($target, $base)。

常見坑點

  1. 輸入為文件路徑時,必須先 dirname() 取目錄,否則會多算一層。
  2. Windows 路徑分隔符 \ 需統一轉換。
  3. 跨磁盤盤符(C: vs D:)無相對路徑,應返回絕對路徑或拋出異常。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved