2013-08-02 8 views
28

Ich suchte vor kurzem eine Möglichkeit, das Protokoll, unter dem URL-Anforderung an den Server geliefert wurde, ordnungsgemäß zu bestimmen. diese

Ich sah durch parse_url() und obwohl $_SERVER superglobale Variable und gefunden:

<?php 
header('Content-Type: text/plain'); 

print_r($_SERVER); 
?> 

Ausgang:

[REQUEST_SCHEME] => http

Allerdings war ich nicht in der Lage um es auf php.net oder Google zu finden. Obwohl ich in der Lage war, this Frage zu finden. Q # 1: Wenn $_SERVER['REQUEST_SCHEME'] wurde nicht dokumentiert, dann ist es wahrscheinlich unzuverlässig, oder es kann vertraut werden?

Ich verwende VC9 PHP 5.4.14 TS unter Windows für die Entwicklung. Aber meine Produktion ist unter Ubuntu. Q # 2: Ist diese Eigenschaft auch unter Ubuntu Linux verfügbar?

Antwort

29

Es ist schwer zu beweisen, dass es zuverlässig ist, aber es ist einfach zu beweisen, dass es nicht zuverlässig ist (wenn ich nur einen Fall liefern könnte, die es nicht funktioniert). Und ich kann beweisen, dass es unzuverlässig ist, weil es nicht mit funktioniert IIS 7.0 + PHP 5.3

+7

+1 zu bestimmen, für nette logische Antworten. –

+0

Danke. Meine Produktion mit 'PHP 5.4.17' zeigt es auch nicht. – BlitZ

+0

Zend Server CE unter Windows auch nicht! – Benjamin

6

Auch ich kann nicht einen Verweis auf REQUEST_SCHEME, finde aber wenn Sie schauen, um zu bestimmen, ob eine Anforderung von http: oder https: gemacht wurde, dann können Sie $_SERVER['HTTPS'] verwenden, die zu einem nicht leeren Wert gesetzt wird, wenn Eine Anfrage wurde von https: gestellt. Es ist dokumentiert auf der PHP-Seite here

+5

In bestimmten Zustand '$ _SERVER [einen Blick toxalot des nehmen‘ HTTPS '] 'gibt einen nicht leeren Wert (' off'), der angibt, dass HTTPS NICHT verwendet wurde. Mehr darüber auf der Seite, die in der Antwort verbunden ist. –

+0

@ F-3000 Danke für die Notiz. Es ist sehr nützlich. – BlitZ

+11

'' 'isset ($ _ SERVER ['HTTPS']) && 'on' === $ _SERVER ['HTTPS']' '' scheint der sicherste Weg zu sein, https: // –

43

Die REQUEST_SCHEME Umgebungsvariable auf den Apache mod_rewrite page dokumentiert. Es wurde jedoch erst mit Apache 2.4 verfügbar.

Ich habe nur Apache 2.2, also habe ich eine Umgebungsvariable erstellt. Ich habe am Anfang meiner .htaccess-Datei Folgendes hinzugefügt.

RewriteEngine on 

# Set REQUEST_SCHEME (standard environment variable in Apache 2.4) 
RewriteCond %{HTTPS} off 
RewriteRule .* - [E=REQUEST_SCHEME:http] 

RewriteCond %{HTTPS} on 
RewriteRule .* - [E=REQUEST_SCHEME:https] 

Jetzt kann ich

  • %{ENV:REQUEST_SCHEME} in anderen Rewrite Bedingungen verwenden und Regeln
  • $_SERVER['REQUEST_SCHEME'] in meinem PHP-Code

Ich muss nicht überall tun zusätzliche unordentlich bedingte Kontrollen und mein PHP-Code ist vorwärtskompatibel. Wenn Apache aktualisiert wird, kann ich meine .htaccess Datei ändern.

Ich weiß nicht, wie Sie dies auf eine Windows-Umgebung anwenden würden. Dies ist wahrscheinlich keine gute Lösung für verteilten Code, aber es funktioniert gut für meine Bedürfnisse.

+0

Trotzdem danke. Es ist gut zu wissen, woher es kommt. – BlitZ

5

In der neuen Version Nginx, standardmäßig fastcgi_param REQUEST_SCHEME $scheme eingestellt.

3

Da diese Variable nicht in allen Serverversionen verfügbar ist, ist es sicherlich nicht zuverlässig, sie nur zu testen. Stattdessen können Sie Ihre PHP-Code ändern zwei Umgebung mehr Servervariablen zu testen, die auch zeigen können, dass https verwendet wird, wie folgt:

if ((! empty($_SERVER['REQUEST_SCHEME']) && $_SERVER['REQUEST_SCHEME'] == 'https') || (! empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (! empty($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == '443')) { 
    $server_request_scheme = 'https'; 
} else { 
    $server_request_scheme = 'http'; 
} 

Wie toxalot sagte, ist REQUEST_SCHEME eine native Variable von Apache seit Version 2.4 (Apache 2.2 hat es nicht). Und wenn die Variable nicht vom Server gesetzt wird, wird PHP sie nicht in ihr globales Array $ _SERVER einschließen.

Zum Glück für die Kompatibilität mit Codes basiert auf exclusevily REQUEST_SCHEME zu überprüfen, können Sie diese Variable in Apache 2.2 Bearbeitung alle Host-Konfigurationsdateien (httpd.conf, ssl.conf, 000-default.conf, erstellen vhosts.conf), indem die folgenden Zeilen:

# FOR HOSTS LISTENING AT PORT 80 
SetEnvIf Request_Protocol ^HTTP/ REQUEST_SCHEME=http 

# FOR HOSTS LISTENING AT PORT 443 
SetEnvIf Request_Protocol ^HTTP/ REQUEST_SCHEME=https 
2

für CloudFlare Benutzer toxalot Vorschlag Verbesserung:

RewriteEngine on 

RewriteCond %{HTTPS} !on [OR] 
RewriteCond %{HTTP:CF-Visitor} '"scheme":"http"' 
RewriteRule .* - [E=REQUEST_SCHEME:http] 

RewriteCond %{HTTPS} on [OR] 
RewriteCond %{HTTP:CF-Visitor} '"scheme":"https"' 
RewriteRule .* - [E=REQUEST_SCHEME:https] 
+0

Ich sollte hinzufügen, dass diese Kopfzeile JSON ist und technisch Platz nach dem Doppelpunkt hinzufügen und die Logik dieser Konfiguration brechen könnte, aber natürlich verstehe ich, dass Apache nicht JSON und Cloudflare Mitarbeiter zu analysieren wissen wahrscheinlich, dass Menschen String tun Übereinstimmungen innerhalb des JSON. Weitere Informationen zu Cloudflare-Spezialköpfen: https://support.cloudflare.com/hc/en-us/articles/200170986-How-does-CloudFlare-handle-HTTP-Request-headers- –

1

Dieser Wert hängt von Ihrem Web-Server. Wenn Sie nginx (v1.10) verwenden, in der Datei /etc/nginx/fastcgi_params können Sie diese folgenden Zeilen sehen:

fastcgi_param REQUEST_SCHEME  $scheme; 
fastcgi_param HTTPS    $https if_not_empty; 

Im allgemeinen ist dieser Standardwert ausreichend sind. Aber es ist möglich, dass es nicht funktioniert, Sie diese Werte in Ihrem vhost zwingen kann:

include fastcgi_params; 
fastcgi_param REQUEST_SCHEME  https; 
fastcgi_param HTTPS    On; 

Wenn Sie Apache verwenden, können Sie Antwort

Verwandte Themen