Relativer Pfad zu einem Verzeichnis
Es gibt meines Wissens keine vordefinierte Funktion in PHP, die - ausgehend
von einem absoluten Verzeichnispfad - den relativen Pfad zu einem anderen
Verzeichnis liefert. Ich bin z.B. im Verzeichnis
/wwwroot/123456/78/9/htdocs/kontakt
und möchte den relativen
Pfad zu /wwwroot/123456/78/9/htdocs/blog/images
wissen.
Wie sieht eine Funktion aus, die die Lösung ../blog/images
liefert? Ich muss ein Verzeichnis nach oben zu
/wwwroot/123456/78/9
und dann runter zu
blog/images
. Dieses Resultat kann ich z.B. in Links zur
Navigation zwischen HTML-Seiten verwenden. Die Funktion muss also
- ermitteln, wie viele Verzeichnisebenen der Quellpfad hat,
- feststellen, welche Verzeichnisebene als erste unterschiedlich ist und
- anhand dieser Ergebnisse den relativen Pfad zusammenbauen.
Verzeichnisebene ermitteln
Die Verzeichnisebene kann ermittelt werden, indem z.B. das Zeichen "/" im Pfad gezählt wird. Vorher muss ggf. der Pfad um Substrings wie "///" oder "../../" bereinigt werden.
$from = "/wwwroot/123456/78/9/htdocs/kontakt"; $fromLevel = substr_count($from, "/");
Die letzte Ebene ist auf dem Level 6.
Wo ist der erste unterschiedliche Name?
Das erste unterschiedliche Verzeichnis wird ermittelt, indem beide Pfade mit
explode()
gesplittet und beide resultierende Arrays verglichen
werden. Identische Namensbestandteile am Anfang werden gestrichen.
/wwwroot/123456/78/9/htdocs/kontakt
/wwwroot/123456/78/9/htdocs/blog/images
$fromParts = explode("/", $from); $toParts = explode("/", $to); for ($i = 0; $i < min(count($fromParts), count($toParts)); $i++) { if ($fromParts[$i] != $toParts[$i]) { break; } } // $i contains the first level on which the folder names are different
Relativen Pfad zusammenbauen
Jetzt muss nur noch der relative Pfad zusammengebaut werden. Das erfolgt mit
$relpath = str_repeat("../", $fromLevel - $i + 1) . implode("/", array_slice($toParts, $i));
Die vollständige Funktion
Die vollständige Funktion sieht damit so aus:
function getRelpath($from, $to) { $fromLevel = substr_count($from, "/"); $toLevel = substr_count($to, "/"); $fromParts = explode("/", $from); $toParts = explode("/", $to); for ($i = 0; $i < min(count($fromParts), count($toParts)); $i++) { if ($fromParts[$i] != $toParts[$i]) { break; } } // $i contains the first level on which the folder names are different return str_repeat("../", $fromLevel - $i + 1) . implode("/", array_slice($toParts, $i)); } // getRelpath