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

PHP 計算兩個文件路徑之間的相對路徑

     編輯:PHP 相關知識

需求場景

給定兩個文件的絕對或相對路徑,計算從文件 A 到文件 B 的相對路徑(如 ../../z/x/y.php),常用於模板引擎、資源引用、構建工具。

核心算法

  1. 將路徑按 / 分割為數組。
  2. 彈出最後一個元素(文件名),剩餘為目錄層級。
  3. 從根開始比較,找到第一個不同的目錄索引 $i。
  4. 文件 A 需向上返回 $a_len - $i 級(每級 ../)。
  5. 文件 B 從 $i 開始拼接剩餘目錄及文件名。

實現代碼

<?php
/**
 * 計算從 $pathA 到 $pathB 的相對路徑
 * @param string $pathA 起始文件路徑
 * @param string $pathB 目標文件路徑
 * @return string 相對路徑
 */
function getRelativePath($pathA, $pathB) {
    // 統一分隔符,去除首尾斜杠
    $pathA = trim(str_replace('\\', '/', $pathA), '/');
    $pathB = trim(str_replace('\\', '/', $pathB), '/');

    $arrA = explode('/', $pathA);
    $arrB = explode('/', $pathB);

    // 彈出文件名
    $fileA = array_pop($arrA);
    $fileB = array_pop($arrB);

    $lenA = count($arrA);
    $lenB = count($arrB);

    // 找到公共前綴長度
    $i = 0;
    while ($i < $lenA && $i < $lenB && $arrA[$i] === $arrB[$i]) {
        $i++;
    }

    $rel = '';
    // 向上返回
    for ($j = 0; $j < $lenA - $i; $j++) {
        $rel .= '../';
    }
    // 向下進入
    for (; $i < $lenB; $i++) {
        $rel .= $arrB[$i] . '/';
    }
    $rel .= $fileB;

    return $rel;
}

// 測試
$pathA = 'a/b/c/d/e/f.php';
$pathB = 'a/b/z/x/y.php';
echo getRelativePath($pathA, $pathB); // 輸出: ../../../z/x/y.php

// 邊界測試
echo getRelativePath('a/b/c.php', 'a/b/d.php'); // d.php
echo getRelativePath('a/b/c.php', 'x/y/z.php'); // ../../x/y/z.php
echo getRelativePath('/var/www/a.php', '/var/www/b.php'); // b.php
?>

進階:基於 SplFileInfo 的現代寫法 (PHP 5.3+)

function getRelativePathModern($from, $to) {
    $from = (new SplFileInfo($from))->getRealPath();
    $to   = (new SplFileInfo($to))->getRealPath();
    if ($from === false || $to === false) return false;

    $fromParts = explode(DIRECTORY_SEPARATOR, $from);
    $toParts   = explode(DIRECTORY_SEPARATOR, $to);

    array_pop($fromParts); // 移除文件名
    array_pop($toParts);

    $i = 0;
    while (isset($fromParts[$i]) && isset($toParts[$i]) && $fromParts[$i] === $toParts[$i]) {
        $i++;
    }

    $up = count($fromParts) - $i;
    $rel = str_repeat('..' . DIRECTORY_SEPARATOR, $up);
    $rel .= implode(DIRECTORY_SEPARATOR, array_slice($toParts, $i));
    $rel .= DIRECTORY_SEPARATOR . basename($to);

    return $rel;
}

注意事項

  • 輸入路徑建議先 realpath() 解析符號鏈接、統一分隔符。
  • 跨盤符(Windows C: vs D:) 無相對路徑,需返回絕對路徑或報錯。
  • 若目標是目錄而非文件,調整彈出邏輯。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved