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

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

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

当前回答

如果你不能控制web服务器,也不知道设置了哪些变量,可以上传这个php来查看:

<?php
echo "<br>1 ".$_SERVER["HTTPS"];
echo "<br>2 ".$_SERVER["SERVER_PORT"];
echo "<br>3 ".$_SERVER["HTTP_X_FORWARDED_PROTO"];
echo "<br>4 ".$_SERVER["HTTP_X_FORWARDED_SSL"];
echo "<br>5 ".$_SERVER["HTTP_HTTPS"];
echo "<br>6 ".$_SERVER["REQUEST_SCHEME"];
?>

<html>
<body>
<br>
Just cruising
</body>
</html>

其他回答

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

/* 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变量,因为它是一个总是工作的直接复制粘贴。可以在产品脚本中使用此片段。

您可以检查$_SERVER['SERVER_PORT'],因为SSL通常运行在端口443上,但这并不是万无一失的。

我的解决方案(因为标准条件[$_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

我刚刚有一个问题,我正在使用Apache mod_ssl运行服务器,然而phpinfo()和var_dump($_SERVER)显示PHP仍然认为我在端口80上。

这是我的解决办法,任何人有同样的问题....

<VirtualHost *:443>
  SetEnv HTTPS on
  DocumentRoot /var/www/vhost/scratch/content
  ServerName scratch.example.com
</VirtualHost>

值得注意的是SetEnv线。有了这些,在重新启动之后,您应该有了您一直梦想的HTTPS环境变量

如果您正在使用Incapsula的负载均衡器,则需要使用IRule为您的服务器生成自定义报头。我创建了一个HTTP_X_FORWARDED_PROTO头,等于“http”,如果端口设置为80和“https”,如果它等于443。