PHP 获取站点 URL 协议 - http 与 https

Posted

技术标签:

【中文标题】PHP 获取站点 URL 协议 - http 与 https【英文标题】:PHP Get Site URL Protocol - http vs https 【发布时间】:2011-05-29 00:53:16 【问题描述】:

我编写了一个小函数来建立当前站点的 url 协议,但我没有 SSL,也不知道如何测试它是否在 https 下工作。 你能告诉我这是否正确吗?

function siteURL()

    $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
    $domainName = $_SERVER['HTTP_HOST'].'/';
    return $protocol.$domainName;

define( 'SITE_URL', siteURL() );

有必要像上面那样做还是我可以像上面那样做?:

function siteURL()

    $protocol = 'http://';
    $domainName = $_SERVER['HTTP_HOST'].'/'
    return $protocol.$domainName;

define( 'SITE_URL', siteURL() );

在SSL下,即使锚标签url使用http,服务器不会自动将url转换为https吗?是否需要检查协议?

谢谢!

【问题讨论】:

安装本地 Web 服务器并在其上添加自签名 SSL 证书不是更好的选择吗?这样你就可以自己测试了。 是的,那太棒了,但我不知道该怎么做。 虽然这不能回答您的问题,但您的问题的更好解决方案(虽然我无法确定不知道更多)可能是使用Protocol Relative URLs。 只是一个简单的问题......如果它不是动态的,你怎么会做一个函数。这不像你给它提供任何变量来更改网址。为什么不定义一个常数?这就是我所做的。 $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? “https://”:“http://”;定义('SITE_URL', $protocol.$_SERVER['HTTP_HOST'].'/'); 我可以建议这个吗? ***.com/questions/6768793/get-the-full-url-in-php 【参考方案1】:

我知道我参加这个聚会有点晚了,但是如果您更喜欢不使用 $_SERVER,因为我们强烈建议您不要使用它,甚至在某些 PHP 框架上禁用它; 并且你有一个 apache 网络服务器,你可以使用它的原生命令:-

$protocol = apache_getenv('HTTPS') ? 'https:' : 'http:';

【讨论】:

【参考方案2】:

我认为完整的 func 应该是这样的:

function siteURL()

    $protocol =  "http://";
    if (
        //straight
        isset($_SERVER['HTTPS']) && in_array($_SERVER['HTTPS'], ['on', 1])
        ||
        //proxy forwarding
        isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'
    ) 
        $protocol = 'https://';
    

    $domainName = $_SERVER['HTTP_HOST'];
    return $protocol . $domainName;

注意事项:

您还应该寻找 HTTP_X_FORWARDED_PROTO(例如,如果代理 服务器) 依赖 443 端口是不安全的(https 可以服务于 不同的端口) REQUEST_SCHEME 不可靠

【讨论】:

【参考方案3】:

我知道已经晚了,虽然有一种更方便的方法可以解决这类问题!其他解决方案非常混乱;我会这样做:

$protocol = stripos($_SERVER['SERVER_PROTOCOL'],'https') === 0 ? 'https://' : 'http://';

...如果您愿意,甚至可以无条件:

$protocol = strtolower(substr($_SERVER["SERVER_PROTOCOL"],0,strpos( $_SERVER["SERVER_PROTOCOL"],'/'))).'://';

看看$_SERVER["SERVER_PROTOCOL"]

【讨论】:

这不适用于“https”***.com/questions/16825243/… @wormhit 这主要取决于您的网络服务器的配置方式 你为什么使用stripos而不是strpos $_SERVER['SERVER_PROTOCOL'] 用于存储 HTTP/1.0HTTP/1.1,具体取决于协议版本,您谈论的是哪种 HTTP 服务器配置,存储 https 关于此字符串的信息来自http 查询? 在我的情况下不起作用! $_SERVER['SERVER_PROTOCOL'] 包含“HTTP”(没有任何“S”),而协议是 https。检查 $_SERVER['HTTPS'] 更合适。【参考方案4】:

从 CodeIgniter 中提取:

if ( ! function_exists('is_https'))

    /**
     * Is HTTPS?
     *
     * Determines if the application is accessed via an encrypted
     * (HTTPS) connection.
     *
     * @return  bool
     */
    function is_https()
    
        if ( ! empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off')
        
            return TRUE;
        
        elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https')
        
            return TRUE;
        
        elseif ( ! empty($_SERVER['HTTP_FRONT_END_HTTPS']) && strtolower($_SERVER['HTTP_FRONT_END_HTTPS']) !== 'off')
        
            return TRUE;
        

        return FALSE;
    

【讨论】:

【参考方案5】:

我知道这是一个老问题,但我今天遇到了这个问题,因为我需要在我的网站上对此进行测试。看来上面的答案是不必要的复杂。建立站点协议,只需测试$_SERVER['HTTPS']

如果协议使用的是 HTTPS,那么$_SERVER['HTTPS'] 将返回“on”。如果不是,该变量将保持为空。 例如: // test if HTTPS is being used. If it is, the echo will return '$SSL_test: on'. If not HTTPS, '$SSL_test' will remain empty.

$SSL_test = $_SERVER['HTTPS'];

echo '<p>$SSL_test: '.$SSL_test.'</p>';

if($SSL_test == true) 
    echo 'You\'re using SSL';
 else 
    echo 'You\'re not using SSL';
 

您可以使用上述方法轻松、干净地测试 HTTPS 并相应地实施。 :)

【讨论】:

不是每个服务器都有这个 $_SERVER['HTTPS']【参考方案6】:

这是我的做法......这是速记if else版本的Rid Iculous回答......

$protocol = isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] === 'on' || $_SERVER['HTTPS'] === 1) || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https' ? 'https' : 'http';

【讨论】:

【参考方案7】:

这是 https 或 http 的最佳解决方案,使用这个:

<?php
$protocol = '//';  
$site_url = $protocol.$_SERVER["HTTP_HOST"];
?>

但不能显示https或http,所以它只用于链接你的网站内容,如图片等。

如果想在 https 中重定向您的网站,请将此代码添加到 .htaccess 文件中:

<IfModule mod_rewrite.c>
 RewriteCond %HTTP:CF-Visitor '"scheme":"http"'
 RewriteRule ^(.*)$ https://www.your-domain.com$1 [L]
</IfModule>

www.your-domain.com 更改为您的域名。

【讨论】:

【参考方案8】:

对于除 IIS 之外的任何系统,这足以定义站点自身 URL:

$siteURL='http'.(empty($_SERVER['HTTPS'])?'':'s').'://'.$_SERVER['HTTP_HOST'].'/';

$siteURL='http'.(empty($_SERVER['HTTPS'])?'':'s').'://'.$_SERVER['SERVER_NAME'].'/';

取决于你到底想要什么: HTTP_HOST vs. SERVER_NAME

【讨论】:

【参考方案9】:

如果是代理,SERVER_PORT 可能不会给出正确的值,所以这对我有用 -

$protocol = ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') || $_SERVER['SERVER_PORT'] == 443 || $_SERVER['HTTP_X_FORWARDED_PORT'] == 443) ? "https://" : "http://"

【讨论】:

【参考方案10】:
$protocal = 'http';
if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' || $_SERVER['HTTPS'] == 'on') $protocal = 'https';


echo $protocal;

【讨论】:

【参考方案11】:

我测试了most voted answer,它对我不起作用,我最终使用:

$protocol = isset($_SERVER['HTTPS']) ? 'https://' : 'http://';

【讨论】:

一些网络服务器不支持$_SERVER["HTTPS"],因此您的代码可能会返回http://,即使它应该是https:// 如果服务器不支持https,为什么代码还会返回https 我的服务器支持 https,但从未定义过 $_SERVER["HTTPS"] 变量。 我被你的 2 cmets 弄糊涂了。如果您创建一个涵盖这些特殊情况的新答案可能会更好。谢谢,祝你好运!【参考方案12】:

使用此服务器变量获取协议详细信息:

 $scheme = $_SERVER['REQUEST_SCHEME'] . '://';
 echo $scheme; //it gives http:// or https://

请注意,此服务器变量不可靠。有关更多信息,请查看: Is $_SERVER['REQUEST_SCHEME'] reliable?

【讨论】:

您能否在帖子中添加更多信息,而不仅仅是代码?例如解释为什么这是问题的答案?【参考方案13】:

短途

$scheme = $_SERVER['REQUEST_SCHEME'] . '://';

【讨论】:

REQUEST_SCHEME 不可靠 REQUEST_SCHEME 在 Apache 2.4 之前不可用。【参考方案14】:

因为在我看来测试端口号不是一个好习惯,所以我的解决方案是:

define('HTTPS', isset($_SERVER['HTTPS']) && filter_var($_SERVER['HTTPS'], FILTER_VALIDATE_BOOLEAN));

如果设置了$_SERVER['HTTPS'] 并且等于“1”、“true”、“on”或“yes”,则HTTPSconstant 返回TRUE。 否则返回 FALSE。

【讨论】:

这可能是最好的答案。很多这些答案只会在一定比例的情况下出现。例如,人们只是在检查是否设置了 $_SERVER['HTTPS']。许多框架将此变量设置为 false 或 'off' 等,因此检查它是否只是设置将不起作用。 虽然这在大多数情况下都有效,但有时会出现配置 SNAFU 并且 $_SERVER['HTTPS'] 实际上设置为“关闭”。您的代码仍会将其视为“通过”测试,因此应进行修改以允许该特定设置。【参考方案15】:

使用 Rid Iculous 的答案制作了一个功能,该答案适用于我的系统。

function site_protocol() 
    if(isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1) || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &&  $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')  return $protocol = 'https://'; else return $protocol = 'http://';

希望对你有帮助

【讨论】:

【参考方案16】:

一些变化:

function siteURL() 
  $protocol = ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') || 
    $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
  $domainName = $_SERVER['HTTP_HOST'];
  return $protocol.$domainName;

【讨论】:

【参考方案17】:

这对我有用

if (isset($_SERVER['HTTPS']) &&
    ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1) ||
    isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &&
    $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') 
  $protocol = 'https://';

else 
  $protocol = 'http://';

【讨论】:

这是在使用代理时有效的解决方案(例如在我的情况下为 CloudFlare) 这是正确的 - 你不应该仅仅因为你使用的是 443 端口就假设 https。 这适用于普通链接以及 CDN,谢谢【参考方案18】:

这不是自动的。您的***功能看起来不错。

【讨论】:

值得注意的是,如果您离开协议,它是自动的.. 即//mysqite.com 而不是https://mysitecom @Pamblam, // 效果很好,除非您的链接在电子邮件中 ​​:) 或在 xhr 请求中

以上是关于PHP 获取站点 URL 协议 - http 与 https的主要内容,如果未能解决你的问题,请参考以下文章

PHP 从多个 URL 获取站点标题

将URL拆分为协议站点和资源部分

PHP:获取 HTTP 协议版本(HTTP/1.1 与 HTTP/2)

HttpClient获取数据

HTTP协议

PHP - 简单获取页面内容