私は最近、URLリクエストがサーバーに提供されるプロトコルを適切に決定する方法を探していました。
parse_url()
を介して $_SERVER
スーパーグローバル変数、そしてこれを見つけました:
<?php
header('Content-Type: text/plain');
print_r($_SERVER);
?>
出力:
[REQUEST_SCHEME] => http
ただし、 php.net またはGoogleで見つけることができませんでした。しかし、私は this の質問を見つけることができました。 Q#1:If $_SERVER['REQUEST_SCHEME']
文書化されていなかったので、おそらく信頼できないか、信頼できるか?
使っています VC9 PHP 5.4.14 TS
開発用ウィンドウの下。しかし、私の作品はubuntuの下にあります。 Q#2:このプロパティはubuntu linuxでも利用可能ですか?
信頼性があることを証明するのは難しいですが、信頼性がないことを証明するのは簡単です(うまくいかないケースを提供できれば)。そして、IIS 7.0 + PHP 5.では動作しないため、信頼できないことを証明できます。
REQUEST_SCHEME
環境変数は Apache mod_rewriteページ に記載されています。ただし、Apache 2.4まで使用できませんでした。
Apache 2.2しか持っていないので、環境変数を作成しました。 .htaccessファイルの先頭に次を追加しました。
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]
今、私は使用することができます
%{ENV:REQUEST_SCHEME}
他の書き換え条件とルール$_SERVER['REQUEST_SCHEME']
in my PHP codeどこでも余分な面倒な条件チェックを行う必要はありません。また、私のPHPコードは上位互換性があります。Apacheがアップグレードされると、.htaccessファイルを変更できます。
これをWindows環境にどのように適用するかわかりません。これはおそらく分散コードには適したソリューションではありませんが、私のニーズには適しています。
この変数はすべてのバージョンのサーバーで使用できるわけではないため、信頼できるテストのみではありません。代わりに、PHPコードを変更して、さらに2つのサーバー環境変数をテストできます。これは、以下のようにhttpsが使用されていることを示すこともできます。
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';
}
Toxalotで述べたように、REQUEST_SCHEMEはバージョン2.4以降のApache Webサーバーのネイティブ変数です。 Apache 2.2にはありません( Apache 2.2サーバー変数) があり、Microsoft IIs 8.5にもありません( IIS 8.5サーバー変数) があります。当然、サーバーによって変数が設定されていない場合、PHPはその変数をグローバル配列$ _SERVERに含めません。
幸いなことに、REQUEST_SCHEMEチェックのみに基づいたコードとの互換性のために、Apache 2.2編集でこの変数を作成できますallホスト設定ファイル(httpd.conf、ssl .conf、000-default.conf、vhosts.conf)、次の行を追加します。
# 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
上記のコードは、すべてのプロトコルに1つの仮想ホストを使用することを前提としています(Apacheのベストプラクティス- this および that を参照)。
私もREQUEST_SCHEME
への参照を見つけることができませんでしたが、リクエストがhttp:
またはhttps:
によって行われたかどうかを確認したい場合は、$_SERVER['HTTPS']
を使用できます。 https:
によって。 PHPサイト ここ に文書化されています
新しいバージョンのNginxでは、デフォルトでfastcgi_param REQUEST_SCHEME $scheme
。
この値はWebサーバーによって異なります。 nginx(v1.10)を使用する場合、ファイル/etc/nginx/fastcgi_params
次の行が表示されます。
fastcgi_param REQUEST_SCHEME $scheme;
fastcgi_param HTTPS $https if_not_empty;
通常、このデフォルト値で十分です。しかし、動作しない可能性があります。vhostでこの値を強制することができます。
include fastcgi_params;
fastcgi_param REQUEST_SCHEME https;
fastcgi_param HTTPS On;
Apacheを使用している場合は、toxalotの答えをご覧ください
CloudFlareユーザーに対するtoxalotの提案の強化:
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]
WordPress=が$ -SERVER変数を使用する is_ssl() 関数でこの問題を解決する方法を見るのは興味深い
function is_ssl() {
if ( isset( $_SERVER['HTTPS'] ) ) {
if ( 'on' == strtolower( $_SERVER['HTTPS'] ) ) {
return true;
}
if ( '1' == $_SERVER['HTTPS'] ) {
return true;
}
} elseif ( isset( $_SERVER['SERVER_PORT'] ) && ( '443' == $_SERVER['SERVER_PORT'] ) ) {
return true;
}
return false;
}
私はこれを使用していますが、現在のスキームを取得する最良の方法だと思います
$protocol = stripos($_SERVER['SERVER_PROTOCOL'], 'https') === false ? 'http' : 'https';