我在网上看到过很多教程,说你需要检查$_SERVER['HTTPS'],如果服务器连接是HTTPS安全的。我的问题是,在我使用的一些服务器上,$_SERVER['HTTPS']是一个未定义的变量,导致错误。是否有另一个变量我可以检查,总是应该定义?

只是为了清楚一点,我目前正在使用这段代码来解决它是否是一个HTTPS连接:

if(isset($_SERVER['HTTPS'])) {
    if ($_SERVER['HTTPS'] == "on") {
        $secure_connection = true;
    }
}

当前回答

在我的服务器(Ubuntu 14.10, Apache 2.4, php 5.5)变量$_SERVER['HTTPS']没有设置,当php脚本通过HTTPS加载。我不知道怎么了。但是在.htaccess文件中的下面几行可以修复这个问题:

RewriteEngine on

RewriteCond %{HTTPS} =on [NC] 
RewriteRule .* - [E=HTTPS:on,NE]

其他回答

这应该总是工作,即使$_SERVER['HTTPS']是未定义的:

function isSecure() {
  return
    (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')
    || $_SERVER['SERVER_PORT'] == 443;
}

该代码与IIS兼容。

根据PHP.net文档和用户评论:

如果通过HTTPS协议查询脚本,请设置为非空值。 注意,当ISAPI与IIS一起使用时,如果请求不是通过HTTPS协议发出的,则该值将为“off”。(同样的行为也被报道为IIS7将PHP作为Fast-CGI应用程序运行)。

还有Apache 1。x服务器(和损坏的安装)可能没有定义$_SERVER['HTTPS'],即使安全连接。尽管不能保证,但按照惯例,端口443上的连接可能使用安全套接字,因此需要进行额外的端口检查。

另外注意:如果在客户端和服务器之间有一个负载均衡器,这段代码不会测试客户端和负载均衡器之间的连接,而是测试负载均衡器和服务器之间的连接。要测试前一个连接,你必须使用HTTP_X_FORWARDED_PROTO头进行测试,但这要复杂得多;请看这个答案下面的最新评论。

如果你使用nginx作为负载均衡系统检查$_SERVER['HTTP_HTTPS'] == 1其他检查将失败ssl。

在我的服务器(Ubuntu 14.10, Apache 2.4, php 5.5)变量$_SERVER['HTTPS']没有设置,当php脚本通过HTTPS加载。我不知道怎么了。但是在.htaccess文件中的下面几行可以修复这个问题:

RewriteEngine on

RewriteCond %{HTTPS} =on [NC] 
RewriteRule .* - [E=HTTPS:on,NE]
$secure_connection = ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') || (!empty($_SERVER['HTTP_HTTPS']) && $_SERVER['HTTP_HTTPS'] != 'off') || $_SERVER['REQUEST_SCHEME'] == 'https' || $_SERVER['SERVER_PORT'] == 443) ? true : false;

代码正在检查任何可能的东西,也可以在IIS web服务器上工作。Chrome自v44不设置头HTTP: 1,所以检查HTTP_HTTPS是OK的。如果这段代码不匹配https,这意味着您的web服务器或代理服务器配置不佳。Apache本身设置HTTPS标志正确,但当你使用代理(例如nginx)时可能会有问题。你必须在nginx https虚拟主机中设置一些头文件

proxy_set_header   X-HTTPS 1;

并使用一些Apache模块通过从代理中查找X-HTTPS来正确设置HTTPS标志。搜索mod_fakessl, mod_rpaf等。

我知道这个答案有点晚了,但我把一堆答案结合起来,做了一个适用于所有用例的简单函数。

试试这个:

function is_ssl(){
if(isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO']=="https"){ return true; }
elseif(isset($_SERVER['HTTPS'])){ return true; }
elseif($_SERVER['SERVER_PORT'] == 443){ return true; }
else{ return false; }
}

然后使用if,例如:

if(is_ssl()){
// WHAT TO DO IF IT IS SSL / HTTPS
}else{
// WHAT TO DO IF IT IS NOT SSL / HTTPS
}

此代码适用于Cloudflare,共享主机提供商等。

享受。