$_SERVER['HTTP_HOST']和$_SERVER['SERVER_NAME']在PHP中的区别是什么?
什么时候你会考虑使用其中一种而不是另一种,为什么?
$_SERVER['HTTP_HOST']和$_SERVER['SERVER_NAME']在PHP中的区别是什么?
什么时候你会考虑使用其中一种而不是另一种,为什么?
当前回答
正如我在回答中提到的,如果服务器运行在不是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'
其他回答
我对所有答案都不满意。他们中的一些人是正确的,但没有讲述整个故事,没有把问题说清楚。
无论您使用哪个http服务器,HTTP_HOST都应该包含http头主机中从客户端发送的原始值。因此,用户控制的数据不应该被信任。
变量SERVER_NAME是在您的服务器配置中配置的,它可能不会指向正确的URL。例如,在您的web服务器前面可能有一个反向代理,SERVER_NAME是server1和server2,但您不想将用户重定向到server1,而是重定向到用户友好的主机。
因此,HTTP_HOST是更可靠的变量,因为您可能希望客户端请求的主机到达您的PHP应用程序。您不需要比较它们来确保这是一个有效值(它们不一定相等)。有两种方法确保该值有效:
将该值与有效值列表进行比较(您需要知道有效值) 如果值不正确,请确保web服务器返回错误
第一个很容易理解,但在实际场景中可能会有问题(在您的开发环境中是这样,在登台环境中是这样,在生产环境中是这样……等等)。这意味着您需要知道在PHP中什么对这个环境有效。
The second one is something for the server configuration: VirtualHost is a concept for http servers to deliver multiple websites from the same server. As the virtual host is chosen by the http header Host (case insensitive) the client can not control which virtual host is used unless modifying the host. When only one virtual host is configured every value will use this virtual host. You need to configure a second virtual host that is the default (if no other virtual host matches) and always returns an error (for example "not found" or "forbidden").
正如balusC所说,SERVER_NAME是不可靠的,可以在apache配置中更改,服务器的服务器名配置以及您和服务器之间的防火墙。
以下函数总是返回没有端口的真实主机(用户键入的主机),几乎是可靠的:
function getRealHost(){
list($realHost,)=explode(':',$_SERVER['HTTP_HOST']);
return $realHost;
}
如果你想检查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是客户端连接到的虚拟主机。