579 Stimmen

Was ist der Unterschied zwischen HTTP_HOST und SERVER_NAME in PHP?

Was ist der Unterschied zwischen $_SERVER['HTTP_HOST'] y $_SERVER['SERVER_NAME'] in PHP?

Wann würden Sie das eine dem anderen vorziehen und warum?

827voto

BalusC Punkte 1034465

El HTTP_HOST ergibt sich aus dem HTTP-Anfrage-Header und das ist das, was der Client tatsächlich als "Zielhost" der Anfrage verwendet. Die SERVER_NAME ist in der Serverkonfiguration definiert. Welche Sie verwenden sollten, hängt davon ab, wofür Sie sie benötigen. Sie sollten sich jedoch darüber im Klaren sein, dass es sich bei dem einen Wert um einen clientgesteuerten Wert handelt, der für die Verwendung in der Geschäftslogik möglicherweise nicht zuverlässig ist, und bei dem anderen um einen servergesteuerten Wert, der zuverlässiger ist. Sie müssen jedoch sicherstellen, dass der betreffende Webserver über die SERVER_NAME richtig konfiguriert. Am Beispiel von Apache HTTPD ist hier ein Auszug aus seine Dokumentation :

Wenn keine ServerName angegeben ist, versucht der Server, den Hostnamen durch einen Reverse-Lookup der IP-Adresse zu ermitteln. Wenn kein Port im Feld ServerName dann verwendet der Server den Port der eingehenden Anfrage. Für eine optimale Zuverlässigkeit und Vorhersagbarkeit sollten Sie einen expliziten Hostnamen und einen Port mit der Option ServerName Richtlinie.


Update : nach Prüfung die Antwort von Pekka auf deine Frage die einen Link enthält zu Antwort von bobince dass PHP immer den Wert HTTP_HOST den Wert für SERVER_NAME was meinen eigenen Erfahrungen mit PHP 4.x + Apache HTTPD 1.2.x von vor ein paar Jahren widerspricht, habe ich etwas Staub von meiner aktuellen XAMPP-Umgebung auf Windows XP (Apache HTTPD 2.2.1 mit PHP 5.2.8) gepustet, sie gestartet, eine PHP-Seite erstellt, die die beiden Werte ausgibt, eine Java-Testanwendung mit URLConnection zur Änderung der Host Kopfzeile und Tests haben mir gezeigt, dass dies tatsächlich (fälschlicherweise) der Fall ist.

Nachdem ich zunächst PHP verdächtigt und in einigen PHP-Fehlerberichte zu diesem Thema erfuhr ich, dass die Wurzel des Problems im verwendeten Webserver liegt, der fälschlicherweise HTTP Host Kopfzeile, wenn SERVER_NAME wurde beantragt. Also grub ich in Apache HTTPD Fehlerberichte mit verschiedene Stichwörter zu diesem Thema, und ich habe schließlich eine zugehöriger Fehler . Dieses Verhalten wurde etwa ab Apache HTTPD 1.3 eingeführt. Sie müssen UseCanonicalName Richtlinie zu on im <VirtualHost> Eintrag des ServerName en httpd.conf (Beachten Sie auch die Warnung am Ende der das Dokument !).

<VirtualHost *>
    ServerName example.com
    UseCanonicalName on
</VirtualHost> 

Das hat bei mir funktioniert.

Zusammengefasst, SERVER_NAME ist zuverlässiger, aber Sie sind abhängig in der Serverkonfiguration!

75voto

Pekka Punkte 429407

HTTP_HOST ist der vom Client gesendete Zielhost. Er kann vom Benutzer frei manipuliert werden. Es ist kein Problem, eine Anfrage an Ihre Website zu senden und nach einem HTTP_HOST Wert von www.stackoverflow.com .

SERVER_NAME kommt vom Server der VirtualHost Definition und wird daher als zuverlässiger angesehen. Sie kann jedoch unter bestimmten Bedingungen, die mit der Einrichtung Ihres Webservers zusammenhängen, auch von außen manipuliert werden: Siehe dies Diese SO-Frage die sich mit den Sicherheitsaspekten beider Varianten befasst.

Sie sollten sich auch nicht darauf verlassen, dass Sie sicher sind. Was Sie verwenden sollten, hängt also davon ab, was Sie tun wollen. Wenn Sie feststellen wollen, auf welcher Domäne Ihr Skript läuft, können Sie sicher HTTP_HOST solange ungültige Werte, die von einem böswilligen Benutzer stammen, nichts kaputt machen können.

63voto

Simon East Punkte 50819

Wie ich bereits in diese Antwort Wenn der Server auf einem anderen Port als 80 läuft (wie es auf einem Entwicklungs-/Intranet-Rechner üblich sein kann), dann HTTP_HOST enthält den Anschluss, während SERVER_NAME nicht.

$_SERVER['HTTP_HOST'] == 'localhost:8080'
$_SERVER['SERVER_NAME'] == 'localhost'

(Zumindest habe ich das bei Apache-Port-basierten virtuellen Hosts festgestellt)

Beachten Sie, dass HTTP_HOST hace no enthalten :443 wenn Sie mit HTTPS arbeiten (es sei denn, Sie arbeiten mit einem Nicht-Standard-Port, was ich nicht getestet habe).

Wie bereits erwähnt, unterscheiden sich die beiden auch bei der Verwendung von IPv6:

$_SERVER['HTTP_HOST'] == '[::1]'
$_SERVER['SERVER_NAME'] == '::1'

30voto

Daniel Marschall Punkte 3660

Bitte beachten Sie, dass Sie, wenn Sie IPv6 verwenden möchten, wahrscheinlich die Option HTTP_HOST statt SERVER_NAME . Wenn Sie eingeben http://[::1]/ werden die Umgebungsvariablen wie folgt lauten:

HTTP_HOST = [::1]
SERVER_NAME = ::1

Das bedeutet, dass ein mod_rewrite zum Beispiel zu einem unangenehmen Ergebnis führen kann. Beispiel für einen SSL-Redirect:

# SERVER_NAME will NOT work - Redirection to https://::1/
RewriteRule .* https://%{SERVER_NAME}/

# HTTP_HOST will work - Redirection to https://[::1]/
RewriteRule .* https://%{HTTP_HOST}/

Dies gilt NUR, wenn Sie auf den Server ohne einen Hostnamen zugreifen.

8voto

stevewh Punkte 105

Wenn Sie durch eine server.php oder was auch immer prüfen wollen, müssen Sie es mit dem folgenden aufrufen:

<?php
    phpinfo(INFO_VARIABLES);
?>

o

<?php
    header("Content-type: text/plain");

    print_r($_SERVER);
?>

Greifen Sie dann mit allen gültigen URLs für Ihre Website darauf zu und überprüfen Sie den Unterschied.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X