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

PHP 計算兩路徑相對路徑:從 $a 到 $b 的相對路徑演算法實作

     編輯:PHP 綜合知識

題目

$a = '/a/b/c/d/e.php';
$b = '/a/b/12/34/c.php';
// 求 $b 相對於 $a 的相對路徑 → ../../c/d

演算法邏輯

  1. 以 / 分割路徑為陣列
  2. 移除檔名部分 (最後一段)
  3. 從根目錄開始比對共同前綴
  4. $a 剩餘層級數 → 對應 ../ 數量
  5. $b 剩餘層級 → 組成目標路徑

函數實作

<?php
/**
 * 計算 $from 到 $to 的相對路徑
 *
 * @param string $from 來源絕對路徑 (含檔名)
 * @param string $to   目標絕對路徑 (含檔名)
 * @return string 相對路徑
 */
function getRelativePath($from, $to)
{
    // 正規化:統一分隔符、移除重複斜線
    $from = preg_replace('#/+#', '/', $from);
    $to   = preg_replace('#/+#', '/', $to);

    // 分割並移除檔名
    $fromParts = explode('/', rtrim($from, '/'));
    $toParts   = explode('/', rtrim($to, '/'));
    array_pop($fromParts); // 移除 e.php
    array_pop($toParts);   // 移除 c.php

    // 找共同前綴長度
    $common = 0;
    $minLen = min(count($fromParts), count($toParts));
    while ($common < $minLen && $fromParts[$common] === $toParts[$common]) {
        $common++;
    }

    // $from 需往上幾層
    $up = count($fromParts) - $common;
    // $to 從共同祖先往下的路徑
    $down = array_slice($toParts, $common);

    $rel = str_repeat('../', $up) . implode('/', $down);
    return $rel ?: '.';
}
?>

測試驗證

<?php
$a = '/a/b/c/d/e.php';
$b = '/a/b/12/34/c.php';

echo getRelativePath($a, $b); // 輸出: ../../c/d

// 更多測試
echo getRelativePath('/a/b/c.php', '/a/b/d.php');     // d.php
echo getRelativePath('/a/b/c/d.php', '/a/e/f.php');   // ../../e/f
echo getRelativePath('/a/b/c.php', '/a/b/c/d.php');   // c/d
?>

邊界情況處理

  • 相同路徑 → 回傳 .
  • 跨磁碟機 (Windows) → 直接回傳絕對路徑或拋出異常
  • 輸入非絕對路徑 → 先 realpath() 正規化

現代替代:Symfony Path / League URI

<?php
use Symfony\Component\Filesystem\Path;

$rel = Path::makeRelative($b, dirname($a));
// 需 composer require symfony/filesystem
?>
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved