Get the full URL in PHP: Wie man das Rad nicht neu erfindet und keine Performance verliert
\n\nJeder PHP-Entwickler steht früher oder später vor der Aufgabe: "Wie bekomme ich die vollständige URL der aktuellen Seite?". Es scheint einfach – man nimmt $_SERVER['REQUEST_URI'], fügt die Domain hinzu – und fertig. Aber der Teufel steckt, wie immer, im Detail. Die Frage "Get the full URL in PHP" auf Stack Overflow hat tausende Aufrufe und Dutzende Antworten gesammelt. Und das nicht ohne Grund.
In diesem Artikel analysieren wir, wie man die vollständige URL in PHP korrekt, schnell und ohne Fehler abruft. Sie erfahren, worin sich HTTP_HOST von SERVER_NAME unterscheidet, wie man das Protokoll (HTTPS oder HTTP) korrekt ermittelt und warum man Code aus dem Internet nicht blind kopieren sollte. Los geht's!
Warum der einfache Weg nicht immer der beste ist?
\n\nDie naheliegendste Variante sieht so aus:
\n\n<?php\n$fullUrl = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];\n?>\n\nDieser Code funktioniert, aber nur, wenn bei Ihnen:
\n- \n
- Zwingend HTTP (nicht HTTPS) verwendet wird \n
- Kein von 80 oder 443 abweichender Port vorhanden ist \n
- Der Server den Host-Header korrekt übermittelt \n
In der realen Welt sind diese Bedingungen bei weitem nicht immer erfüllt. Wenn die Website über HTTPS läuft, erhalten Sie eine URL mit http://, was im Browser zu einem Fehler wegen gemischten Inhalts führt. Wenn der Port nicht standardmäßig ist (z. B. 8080), geht er verloren. Und wenn ein Angreifer den Host-Header fälscht, können Sie eine URL zu einer fremden Domain erhalten.
\n\nKomponenten der vollständigen URL: Eine detaillierte Analyse
\n\nBevor wir eine universelle Lösung schreiben, erinnern wir uns daran, woraus eine vollständige URL besteht:
\n\nscheme://host:port/path?query#fragment\n\nIn PHP stehen uns die folgenden Elemente aus dem superglobalen Array $_SERVER zur Verfügung:
- \n
- scheme – Protokoll (HTTP oder HTTPS). Es gibt keinen direkten Schlüssel, aber es kann über
$_SERVER['HTTPS']oder$_SERVER['REQUEST_SCHEME'](verfügbar ab PHP 7.4) ermittelt werden. \n - host – Domain. Es gibt zwei Kandidaten:
HTTP_HOST(aus dem Host-Header) undSERVER_NAME(aus der Serverkonfiguration). \n - port – Port.
$_SERVER['SERVER_PORT']. Wenn der Port standardmäßig ist (80 für HTTP, 443 für HTTPS), kann er weggelassen werden. \n - path – Pfad.
$_SERVER['REQUEST_URI']enthält den Pfad und die Query-String. \n - query – Query-String. Kann separat über
$_SERVER['QUERY_STRING']abgerufen werden. \n - fragment – Anker. Er wird nicht an den Server übermittelt und kann daher nicht abgerufen werden. \n
Die richtige Lösung: Die Funktion getFullUrl()
\n\nHier ist eine zuverlässige und performante Methode, um die vollständige URL in PHP abzurufen:
\n\n<?php\nfunction getFullUrl(): string {\n // Protokoll ermitteln\n $scheme = 'http';\n if (\n (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] === 'on' || $_SERVER['HTTPS'] === '1'))\n || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https')\n ) {\n $scheme = 'https';\n }\n\n // Host: HTTP_HOST bevorzugen, aber auf Leerheit prüfen\n $host = $_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'] ?? 'localhost';\n\n // Port: nur hinzufügen, wenn nicht standardmäßig\n $port = (int) ($_SERVER['SERVER_PORT'] ?? 80);\n $portStr = '';\n if (\n ($scheme === 'http' && $port !== 80) ||\n ($scheme === 'https' && $port !== 443)\n ) {\n $portStr = ':' . $port;\n }\n\n // URI\n $uri = $_SERVER['REQUEST_URI'] ?? '/';\n\n return $scheme . '://' . $host . $portStr . $uri;\n}\n?>\n\nDiese Funktion berücksichtigt:
\n- \n
- HTTPS-Protokoll (auch über Proxy-Server mit dem
X-Forwarded-Proto-Header). \n - Nicht standardmäßige Ports. \