$_SERVER['HTTP_HOST']和$_SERVER['SERVER_NAME']在PHP中的区别是什么?

什么时候你会考虑使用其中一种而不是另一种,为什么?


当前回答

如果你想检查server.php或其他什么,你想用下面的方法调用它:

<?php
    phpinfo(INFO_VARIABLES);
?>

or

<?php
    header("Content-type: text/plain");

    print_r($_SERVER);
?>

然后使用您站点的所有有效url访问它,并检查差异。

其他回答

正如我在回答中提到的,如果服务器运行在不是80的端口上(在开发/intranet机器上可能很常见),那么HTTP_HOST包含端口,而SERVER_NAME不包含端口。

$_SERVER['HTTP_HOST'] == 'localhost:8080'
$_SERVER['SERVER_NAME'] == 'localhost'

(至少这是我在Apache基于端口的虚拟主机中注意到的)

注意在HTTPS上运行时HTTP_HOST不包含:443(除非您在非标准端口上运行,我没有测试过)。

正如其他人所指出的,这两者在使用IPv6时也有所不同:

$_SERVER['HTTP_HOST'] == '[::1]'
$_SERVER['SERVER_NAME'] == '::1'

看我想知道什么了。SERVER_NAME是服务器的主机名,而HTTP_HOST是客户端连接到的虚拟主机。

$_SERVER['SERVER_NAME']基于您的web服务器配置。 $_SERVER['HTTP_HOST']是基于来自客户端的请求。

正如balusC所说,SERVER_NAME是不可靠的,可以在apache配置中更改,服务器的服务器名配置以及您和服务器之间的防火墙。

以下函数总是返回没有端口的真实主机(用户键入的主机),几乎是可靠的:

function getRealHost(){
   list($realHost,)=explode(':',$_SERVER['HTTP_HOST']);
   return $realHost;
}

请注意,如果你想使用IPv6,你可能想使用HTTP_HOST而不是SERVER_NAME。如果输入http://[::1]/,则环境变量如下:

HTTP_HOST = [::1]
SERVER_NAME = ::1

这意味着,如果你做一个mod_rewrite,你可能会得到一个糟糕的结果。SSL重定向示例:

# SERVER_NAME will NOT work - Redirection to https://::1/
RewriteRule .* https://%{SERVER_NAME}/

# HTTP_HOST will work - Redirection to https://[::1]/
RewriteRule .* https://%{HTTP_HOST}/

这只适用于在没有主机名的情况下访问服务器。