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

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

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

当前回答

我的系统使用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);

其他回答

只是出于兴趣,铬金丝雀目前发送

HTTPS : 1

发送到服务器,这取决于服务器的配置方式,可能意味着您将返回以下内容

HTTPS : 1, on

这破坏了我们的应用程序,因为我们正在测试是否打开,而它显然没有打开。 目前,只有铬金丝雀似乎可以做到这一点,但值得注意的是,金丝雀的东西通常会在“正常”铬短时间后落地。

如果你正在使用Apache,你可以一直依赖它

$_SERVER["REQUEST_SCHEME"]

验证所请求URL的方案。但是,正如在其他回答中提到的,在假设真的使用SSL之前,验证其他参数是谨慎的。

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

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

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

我有机会进一步确定我要连接的网站是否具有SSL能力(一个项目要求用户提供他们的URL,我们需要验证他们已经在http或https网站上安装了我们的API包)。

这是我使用的函数-基本上,只是通过cURL调用URL,看看https是否有效!

function hasSSL($url) 
{
    // take the URL down to the domain name
    $domain = parse_url($url, PHP_URL_HOST);
    $ch = curl_init('https://' . $domain);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'HEAD'); //its a  HEAD
    curl_setopt($ch, CURLOPT_NOBODY, true);          // no body
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);  // in case of redirects
    curl_setopt($ch, CURLOPT_VERBOSE, 0); //turn on if debugging
    curl_setopt($ch, CURLOPT_HEADER, 1);     //head only wanted
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);    // we dont want to wait forever
    curl_exec($ch);
    $header = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    if ($header === 200) {
        return true;
    }
    return false;
}

这是我发现的最可靠的方法,不仅可以知道你是否正在使用https(正如问题所问的那样),而且可以知道你是否可以(甚至应该)使用https。

注意:有可能(虽然不太可能…)一个网站可以有不同的http和https页面(所以如果你被告知使用http,也许你不需要改变..)绝大多数网站都是一样的,可能需要重新路由你自己,但这个额外的检查是有用处的(当然,就像我说的,在用户输入他们的网站信息的项目中,你想从服务器端确保)

真正的答案:准备复制粘贴到一个[配置]脚本

/* configuration settings; X=edit may 10th '11 */
$pv_sslport=443; /* for it might be different, as also Gabriel Sosa stated */
$pv_serverport=80; /* X */
$pv_servername="mysite.com"; /* X */

/* X appended after correction by Michael Kopinsky */
if(!isset($_SERVER["SERVER_NAME"]) || !$_SERVER["SERVER_NAME"]) {
    if(!isset($_ENV["SERVER_NAME"])) {
        getenv("SERVER_NAME");
        // Set to env server_name
        $_SERVER["SERVER_NAME"]=$_ENV["SERVER_NAME"];
    }
}
if(!$_SERVER["SERVER_NAME"]) (
    /* X server name still empty? ... you might set $_SERVER["SERVER_NAME"]=$pv_servername; */
}

if(!isset($_SERVER["SERVER_PORT"]) || !$_SERVER["SERVER_PORT"]) {
    if(!isset($_ENV["SERVER_PORT"])) {
        getenv("SERVER_PORT");
        $_SERVER["SERVER_PORT"]=$_ENV["SERVER_PORT"];
    }
}
if(!$_SERVER["SERVER_PORT"]) (
    /* X server port still empty? ... you might set $_SERVER["SERVER_PORT"]=$pv_serverport; */
}

$pv_URIprotocol = isset($_SERVER["HTTPS"]) ? (($_SERVER["HTTPS"]==="on" || $_SERVER["HTTPS"]===1 || $_SERVER["SERVER_PORT"]===$pv_sslport) ? "https://" : "http://") :  (($_SERVER["SERVER_PORT"]===$pv_sslport) ? "https://" : "http://");

$pv_URIprotocol现在是正确的,可以使用了;示例网站= pv_URIprotocol美元。$ _SERVER(“SERVER_NAME”)。当然,字符串也可以替换为TRUE和FALSE。PV代表PortalPress变量,因为它是一个总是工作的直接复制粘贴。可以在产品脚本中使用此片段。