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

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

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

当前回答

我使用了这里的主要建议,当没有设置HTTPS时,日志中的“PHP通知”让我很恼火。你可以使用空合并操作符"?? ?":

if( ($_SERVER['HTTPS'] ?? 'off') == 'off' ) {
    // redirect
}

(注意:在php v7之前不可用)

其他回答

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

我的解决方案(因为标准条件[$_SERVER['HTTPS'] == 'on']在负载均衡器后面的服务器上不起作用)是:

$isSecure = false;
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
    $isSecure = true;
}
elseif (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' || !empty($_SERVER['HTTP_X_FORWARDED_SSL']) && $_SERVER['HTTP_X_FORWARDED_SSL'] == 'on') {
    $isSecure = true;
}
$REQUEST_PROTOCOL = $isSecure ? 'https' : 'http';

HTTP_X_FORWARDED_PROTO:标识HTTP请求的初始协议的事实标准,因为反向代理(负载均衡器)可能使用HTTP与web服务器通信,即使反向代理的请求是HTTPS http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Common_non-standard_request_headers

这就是我解决这个问题的方法

$https = !empty($_SERVER['HTTPS']) && strcasecmp($_SERVER['HTTPS'], 'on') === 0 ||
        !empty($_SERVER['HTTP_X_FORWARDED_PROTO']) &&
            strcasecmp($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') === 0;

return ($https) ? 'https://' : 'http://';

我会添加一个全局过滤器,以确保我检查的所有内容都是正确的;

function isSSL() {

    $https = filter_input(INPUT_SERVER, 'HTTPS');
    $port = filter_input(INPUT_SERVER, 'SERVER_PORT');
    if ($https) {

        if ($https == 1) {
            return true;
        } elseif ($https == 'on') {
            return true;
        }
    } elseif ($port == '443') {
        return true;
    }

    return false;
}

我的系统使用cloudflare。我必须访问$_SERVER['HTTP_CF_VISITOR']值。

$isSsl = false; 
    if (isset($_SERVER['HTTP_CF_VISITOR'])) {
        $cfDecode = json_decode($_SERVER['HTTP_CF_VISITOR']);
        if (!empty($cfDecode) && !empty($cfDecode->scheme) && $cfDecode->scheme == 'https') {
            $isSsl = true;
        }
    }
var_dump($isSsl);