others - $_SERVER['REQUEST_SCHEME'] 是否可靠?

我通过parse_url()观察了$_SERVER的全局变量,发现了这个:


<?php


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



print_r($_SERVER);


?>



输出:

[REQUEST_SCHEME] => http

问题,Q#1 :如果$_SERVER['REQUEST_SCHEME']没有文档化,那么它是否可以信任,结果可靠吗?

我在用 VC9 PHP 5.4.14 TS我在Windows下进行开发,但是我的生产机是在ubuntu下运行,Q#2 :这个属性也在ubuntu Linux下也有效?

时间:

很难证明它是可靠的,但是很容易证明它是不可靠的(我能提供一个不工作的案例)。 我可以证明它是不可靠的,因为它不适用于IIS 7.0 PHP 5.3

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}
  • PHP代码中的$_SERVER['REQUEST_SCHEME']

对于分布式代码来说,这可能不是一个好的解决方案,但是它适合我的需求。

我也找不到REQUEST_SCHEME的引用,但是如果你想确定是由http:或https:,那么你可以用$_SERVER['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';


}



如果该变量未由服务器设置,则PHP将不包括在它全局数组$_SERVER.中。

幸运的是,为了与基于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




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]



此值取决于你的web服务器,如果使用Nginx (v1.10 ),则在文件/etc/nginx/fastcgi_params中可以看到以下行:


fastcgi_param REQUEST_SCHEME $scheme; 


fastcgi_param HTTPS $https if_not_empty;



通常,此默认值是足够的,但是可能无法正常工作,你可以在虚拟主机中强制使用以下值:


include fastcgi_params;


fastcgi_param REQUEST_SCHEME https; 


fastcgi_param HTTPS On;



...