php $_SERVER['REQUEST_SCHEME'] 可靠吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18008135/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is $_SERVER['REQUEST_SCHEME'] reliable?
提问by BlitZ
I recently was seeking a way to properly determine protocol, under which url request was supplied to the server.
我最近正在寻找一种方法来正确确定协议,根据该协议将 url 请求提供给服务器。
I watched through parse_url()
and though $_SERVER
superglobal variable, and found this:
我看着通过parse_url()
,虽然$_SERVER
超全局变量,发现这一点:
<?php
header('Content-Type: text/plain');
print_r($_SERVER);
Output:
输出:
[REQUEST_SCHEME] => http
[REQUEST_SCHEME] => http
However, I was unable to find it on php.netor Google. Though, I was able to find thisquestion. Q#1:If $_SERVER['REQUEST_SCHEME']
wasn't documented, then it is probably unreliable, or it can be trusted?
但是,我无法在php.net或 Google上找到它。虽然,我能够找到这个问题。Q#1:如果$_SERVER['REQUEST_SCHEME']
没有记录,那么它可能是不可靠的,还是可以信任的?
I'am using VC9 PHP 5.4.14 TS
under windows for development. But my production is under ubuntu. Q#2:Is this property also availible under ubuntu linux too?
我VC9 PHP 5.4.14 TS
在windows下使用开发。但是我的作品是在 ubuntu 下进行的。Q#2:这个属性在 ubuntu linux 下也可用吗?
采纳答案by invisal
It is hard to prove that it is reliable, but it is easy to prove that it is not reliable (if only I could provide a case which it does not work). And I can prove that it is unreliable because it does not work with IIS 7.0 + PHP 5.3
证明它可靠很难,但证明它不可靠很容易(如果我能提供一个它不起作用的案例)。而且我可以证明它不可靠,因为它不适用于IIS 7.0 + PHP 5.3
回答by toxalot
The REQUEST_SCHEME
environment variable is documented on the Apache mod_rewrite page. However, it didn't become available until Apache 2.4.
该REQUEST_SCHEME
环境变量记录了在Apache的mod_rewrite的页面。但是,它直到 Apache 2.4 才可用。
I only have Apache 2.2 so I created an environment variable. I added the following to the top of my .htaccess file.
我只有 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]
Now I can use
现在我可以使用
%{ENV:REQUEST_SCHEME}
in other rewrite conditions and rules$_SERVER['REQUEST_SCHEME']
in my PHP code
%{ENV:REQUEST_SCHEME}
在其他重写条件和规则中$_SERVER['REQUEST_SCHEME']
在我的 PHP 代码中
I don't have to do extra messy conditional checks everywhere, and my PHP code is forward compatible. When Apache is upgraded, I can change my .htaccess file.
我不必到处做额外的杂乱条件检查,而且我的 PHP 代码是向前兼容的。当 Apache 升级时,我可以更改我的 .htaccess 文件。
I don't know how you'd apply this to a Windows environment. This is probably not a good solution for distributed code, but it works well for my needs.
我不知道您如何将其应用于 Windows 环境。对于分布式代码来说,这可能不是一个好的解决方案,但它可以很好地满足我的需求。
回答by aldemarcalazans
As this variable is not available in all web server versions, it is not reliable testing only it. Instead, you can change your PHP code to test two more server environment variables, which can also indicate that https is being used, as below:
由于此变量并非在所有 Web 服务器版本中都可用,因此仅对其进行测试是不可靠的。相反,您可以更改 PHP 代码以测试另外两个服务器环境变量,这也可以表明正在使用 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';
}
As remarked by toxalot, REQUEST_SCHEME is a native variable of Apache web server since its version 2.4. Apache 2.2 does not have it (see Apache 2.2 server variables)and Microsoft IIs 8.5 does not have it either (see IIS 8.5 Server Variables). Naturally, if a variable is not set by the server, PHP will not include it in its global array $_SERVER.
正如 toxalot 所说,REQUEST_SCHEME 是 Apache Web 服务器自 2.4 版以来的本机变量。Apache 2.2 没有(参见Apache 2.2 服务器变量),Microsoft IIs 8.5 也没有(参见IIS 8.5 服务器变量)。自然,如果服务器未设置变量,PHP 不会将其包含在其全局数组 $_SERVER 中。
Fortunately, for compatibility with codes based exclusively on REQUEST_SCHEME checking, you can create this variable in Apache 2.2 editing allyour host configuration files (httpd.conf, ssl.conf, 000-default.conf, vhosts.conf), adding the following lines:
幸运的是,为了与完全基于 REQUEST_SCHEME 检查的代码兼容,您可以在 Apache 2.2 中创建此变量,编辑所有主机配置文件(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
The code above presume the use of one vhost for every protocol (a best practice in Apache - see thisand that).
回答by aldemarcalazans
I, too, couldn't find a reference to REQUEST_SCHEME
, but if you're looking to determine whether a request was made by http:
or https:
then you can use $_SERVER['HTTPS']
, which is set to a non-empty value if a request was made by https:
. It's documented on the PHP site here
我也一样,找不到一个参考REQUEST_SCHEME
,但如果你正在寻找确定请求是否被提出http:
或者https:
那么你可以使用$_SERVER['HTTPS']
,它被设置为一个非空值,如果一个请求被提出https:
。它记录在PHP站点这里
回答by S.A.N
In new version Nginx, set by default fastcgi_param REQUEST_SCHEME $scheme
.
在新版本的 Nginx 中,默认设置fastcgi_param REQUEST_SCHEME $scheme
.
回答by Arno
This value depends on your web-server. If you use nginx (v1.10), in file /etc/nginx/fastcgi_params
you can see this following lines :
此值取决于您的网络服务器。如果您使用 nginx (v1.10),在文件中/etc/nginx/fastcgi_params
您可以看到以下几行:
fastcgi_param REQUEST_SCHEME $scheme;
fastcgi_param HTTPS $https if_not_empty;
Generally, this default values are sufficient. But it is possible that it does not work, you can force this values in your vhost :
一般来说,这个默认值就足够了。但它可能不起作用,您可以在 vhost 中强制使用此值:
include fastcgi_params;
fastcgi_param REQUEST_SCHEME https;
fastcgi_param HTTPS On;
If you use Apache, you can take a look toxalot's answer
如果你使用Apache,你可以看看toxalot的答案
回答by Aurovrata
Its interesting to see how WordPress resolves this issue with its is_ssl()function which makes use of $_SERVER variable,
有趣的是,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;
}
回答by Sinus Mackowaty
Enhancing toxalot's suggestion for CloudFlare users:
增强 toxalot 对 CloudFlare 用户的建议:
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]
回答by Mr.Hosseini
I'm using this and i think it's best way to get the current scheme
我正在使用这个,我认为这是获得当前方案的最佳方式
/**
* Is Secure?
* Determines if the application is accessed via an encrypted
* (HTTPS) connection.
*
* @return bool
*/
public static function isSecure()
{
if (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off') {
return true;
} elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https') {
return true;
} elseif (!empty($_SERVER['HTTP_FRONT_END_HTTPS']) && strtolower($_SERVER['HTTP_FRONT_END_HTTPS']) !== 'off') {
return true;
} elseif (isset($_SERVER['SERVER_PORT']) && intval($_SERVER['SERVER_PORT']) === 443) {
return true;
}
return false;
}
Define this function and check server ssl connection to get current scheme
定义此函数并检查服务器 ssl 连接以获取当前方案
$scheme = isSecure() ? 'https' : 'http';