Bitte warten...

Pfade in der Webentwicklung

Der Umgang mit absoluten und relativen Dateipfaden gehört wie allgemein in der Programmierung auch in der Webentwicklung zum täglichen Brot. Dennoch gilt es, dabei ein paar Details zu beachten, um die Möglichkeiten voll auszuschöpfen bzw. keine unerwarteten Ergebnisse zu produzieren.

HTML

Pfadangaben in HTML – wie beispielsweise im Attribut href der Elemente <a> und <link> oder im Attribut src der Elemente <img> und <script> – folgen den üblichen Konventionen:

Absolute Pfade zu externen Ressourcen sind vollwertige URLs und beginnen immer mit der Bezeichnung für das jeweilige Internetprotokoll (meist http:// oder https://) gefolgt von dem Hostnamen (z. B. www.decocode.de). Darauf folgt der eigentliche Dateipfad, beginnend mit einem / für das Wurzelverzeichnis („Host-Root“).

Absolute Pfade zu lokalen Ressourcen auf dem Hostsystem beginnen immer mit einem / für das Wurzelverzeichnis, ggf. gefolgt von weiteren Unterverzeichnissen.

Relative Pfade auf eine lokale Ressource werden in der Regel ab dem Verzeichnis des aufrufenden Dokuments gerechnet. Dies kann explizit durch die Zeichen ./ am Beginn des Pfades angegeben werden. Werden diese Zeichen weggelassen, wird das aktuelle Verzeichnis implizit angenommen.

Um einen relativen Pfad zu einem Ort in der Verzeichnishierarchie oberhalb des aufrufenden Dokuments anzugeben, werden dem Pfad die Zeichen ../ für die nächsthöhere Verzeichnisebene vorangestellt. Befindet sich der Ort zwei Ebenen höher, werden diese Zeichen verdoppelt (../../) usw.

Beispiele:

Code kopieren
<a href='https://www.decocode.de/scripts/'>Absoluter Pfad auf eine externe Ressource</a>
<a href='/scripts/inc/face-smile.svg'>Absoluter Pfad auf eine lokale Ressource</a>
<a href='scripts/inc/face-smile.svg'>Relativer Pfad auf eine lokale Ressource (implizit)</a>
<a href='./scripts/inc/face-smile.svg'>Relativer Pfad auf eine lokale Ressource (explizit)</a>
<a href='../../scripts/inc/face-smile.svg'>Relativer Pfad auf eine lokale Ressource (zwei Ebenen höher)</a>

Sollen relative Pfade von einem anderen Verzeichnis aus gerechnet werden, so kann das im <head>-Abschnitt des HTML-Quelltextes im <base>-Element festgelegt werden (s. MDN):

Code kopieren
<head>
  <base href='/scripts/inc/default.php'>
</head>

CSS

Pfade werden in Cascading Style Sheets (CSS) mit url() angegeben (s. MDN). Für sie gelten praktisch die gleichen Konventionen wie oben beschrieben.

Code kopieren
<style>
  /* relative Pfade: */
  @font-face { font-family:Salsa; font-weight:bold; font-style:normal; src:url(inc/Salsa-Regular.ttf); }
  .smile { background-image:url(inc/bg.png); }
  /* absoluter Pfad: */
  .smile::before { content:url(/scripts/inc/face-smile.svg); }
</style>

<link  href='/scripts/inc/styles.css' rel='stylesheet'>

Mit der @import-Regel können CSS-Dateien, die sich an anderen Orten befinden, in ein Stylesheet eingebunden werden (s. MDN). Relative Pfade in diesen Dateien beziehen sich immer auf den Ort, an dem diese Datei gespeichert ist (hier beispielsweise: inc/styles.css), nicht auf den Ort der einbindenden Datei (hier beispielsweise: /scripts/index.php), weshalb diese CSS-Dateien von den unterschiedlichsten Orten aus eingebunden werden können, ohne dass sich dies auf die relativen Pfade in ihnen auswirkt.

Code kopieren
@import url(inc/extra.css);

PHP

Mit den Funktionen include() und require() können PHP-Dateien in andere PHP-Dateien eingebunden werden (s. PHP.net).

Absolute Pfade beziehen sich hier auf das Wurzelverzeichnis des Webservers, das nicht mit dem Wurzelverzeichnis des Hosts identisch ist. Das Wurzelverzeichnis des Webservers („Server-Root“) ist wie bei jedem anderen Rechner auch das oberste Verzeichnis der Verzeichnishierarchie des Dateisystems, also /. In der Regel sind auf diesem Server eine Vielzahl von Hosts in ihren eigenen Verzeichnissen installiert. Die eigene Domain zeigt nun auf das Wurzelverzeichnis eines dieser Hosts („Host-Root“). Der Pfad zu diesem Host ist in der PHP-Variable $_SERVER['DOCUMENT_ROOT'] gespeichert (s. PHP.net).

Beispielsweise lautet die URL einer Ressource:
https://www.decocode.de/scripts/inc/extra.php

Und der Wert von $_SERVER['DOCUMENT_ROOT'] für diese Domain ist:
/var/www/vhosts/web007.server42/httpdocs

Dann ist der vollständige Pfad zu dieser Ressource auf dem Server:
/var/www/vhosts/web007.server42/httpdocs/scripts/inc/extra.php

Bei relativen Pfaden sucht PHP zuerst relativ zu dem aktuellen Dokument (die erste einbindende Datei). Wird hier keine Ressource gefunden, wird danach relativ zu der einbindenden Datei gesucht (falls diese nicht mit dem aktuellen Dokument identisch ist).

Angenommen, es existieren beispielsweise folgende Dateien:
1. /scripts/index.php
2. /scripts/inc/extra.php
3. /scripts/inc/extra2.php
4 ./scripts/inc/inc/extra2.php

Datei 1 bindet Datei 2 mit require("inc/extra.php") ein. Datei 2 bindet Datei 3 mit require("inc/extra2.php") ein. PHP sucht nun zuerst /scripts/inc/extra2.php und bindet diese Datei ein. Wäre diese Datei nicht vorhanden, würde weiter nach /scripts/inc/inc/extra2.php gesucht werden. In diesem Fall würde also Datei 4 eingebunden werden.

Die eingebundenen Dateien werden „räumlich“ so behandelt, als sei ihr gesamter Code schon immer Teil der einbindenen Datei gewesen. Für die in ihnen enthaltenen relativen Pfade gilt also, dass sie sich somit auf den Ort des ersten einbindenden Dokuments beziehen.

Dies gilt insbesondere für die Dateisystem-Funktionen von PHP, aber auch beispielsweise für getimagesize(), exif_read_data() usw.

Code kopieren
<?php
# absoluter Pfad:
  $file = $_SERVER['DOCUMENT_ROOT']."/scripts/inc/extra.php";
  if (file_exists($file)) require($file);

# relativer Pfad:
  $file = "inc/extra2.php";
  if (file_exists($file)) require($file);
?>

Pfade ab Server-Root:

Den vollständigen Pfad zum aktuellen Dokument findet man in der Variable $_SERVER['SCRIPT_FILENAME'], während man den Pfad zu einer eingebundenen Datei in der Variable __FILE__ findet.

Hier die Ausgabe von /scripts/inc/extra.php:

Code kopieren
echo $_SERVER['SCRIPT_FILENAME'];
# Ausgabe: /var/www/vhosts/web007.server42/httpdocs/scripts/index.php

echo __FILE__;
# Ausgabe: /var/www/vhosts/web007.server42/httpdocs/scripts/inc/extra.php

Die Funktion realpath() wandelt einen relativen in einen absoluten Pfad ab Server-Root um (s. PHP.net).

Code kopieren
  $path = "/scripts/inc/extra.php";
  echo realpath($path);
  # Ausgabe: /var/www/vhosts/web007.server42/httpdocs/scripts/inc/extra.php

Pfade ab Host-Root:

Den Pfad zum aktuellen Dokument findet man in der Variable $_SERVER['PHP_SELF']. Den Pfad zu einer eingebundenen Datei kann man mit mb_substr(__FILE__, mb_strlen($_SERVER['DOCUMENT_ROOT'])) ermitteln.

Hier die Ausgabe von /scripts/inc/extra.php:

Code kopieren
echo $_SERVER['PHP_SELF'];
# Ausgabe: /scripts/index.php

echo mb_substr(__FILE__, mb_strlen($_SERVER['DOCUMENT_ROOT']));
# Ausgabe: /scripts/inc/extra.php

Query-String:

Eine eventuell vorhandene Kette mit Variablen, die an eine URL angehängt wurde, kann mit $_SERVER['QUERY_STRING'] ermittelt werden.

$_SERVER['REQUEST_URI'] enthält den gesamten Pfad ab Host-Root einschließlich Query-String.

Code kopieren
# URL = https://www.decocode.de/scripts/index.php?a=100&b=Hallo

echo $_SERVER['QUERY_STRING'];
# Ausgabe: a=100&b=Hallo

echo $_SERVER['REQUEST_URI'];
# Ausgabe: /scripts/index.php?a=100&b=Hallo

Die einzelnen Variablen des Query-Strings befinden sich in dem Array $_GET:
$_GET['a'] == 100
$_GET['b'] == "Hallo"

Pfad zerlegen:

Mit der Funktion dirname() kann ein Pfad vom Dateinamen bereinigt werden (s. PHP.net). Als zusätzliches Argument kann die Anzahl der Ebenen oberhalb der Datei angegeben werden, bis zu der der Pfad beschnitten werden soll.

Mit der Funktion basename() kann der Dateiname aus einem Pfad extrahiert werden (s. PHP.net). Als zusätzliches Argument kann die Dateiendung angegeben werden, die dann abgetrennt wird.

Code kopieren
$path = "/scripts/inc/extra.php";

echo dirname($path);
# Ausgabe: /scripts/inc

echo dirname($path, 2);
# Ausgabe: /scripts

echo basename($path);
# Ausgabe: extra.php

echo basename($path, ".php");
# Ausgabe: extra

Mit der Funktion pathinfo() kann ein Pfad in seine Bestandteile zerlegt werden (s. PHP.net). Zurückgegeben wird ein assoziatives Array mit den Bestandteilen.

Code kopieren
$path = "/scripts/inc/extra2.php";
$parts = pathinfo($path);

/*
Ausgabe:
$parts['dirname']   == "/scripts/inc"
$parts['basename']  == "extra2.php"
$parts['filename']  == "extra2"
$parts['extension'] == "php"
*/

Mit der Funktion parse_url() kann eine URL in ihre Bestandteile zerlegt werden (s. PHP.net). Zurückgegeben wird ein assoziatives Array mit den Bestandteilen.

Code kopieren
$url = "https://www.decocode.de/scripts/index.php?a=100&b=Hallo#details";
$parts = parse_url($url);

/*
Ausgabe:
$parts['scheme']   == "https"
$parts['host']     == "www.decocode.de"
$parts['path']     == "/scripts/index.php"
$parts['query']    == "a=100&b=Hallo"
$parts['fragment'] == "details"
*/