如何在PHP中不使用$ _SERVER ['SERVER_NAME']来获取真正的主机名?还有其他更可靠的方法吗?
我创建了一个从域路径获取主机名的函数。
我想避免使用$ _SERVER ['SERVER_NAME']变量,因为它可以通过在HTTP请求中发送已修改的标头来伪造。
这是我当前的实现(如果路径中包含实际的域名,则此方法有效。例如:/vhosts/website.com/public_html):
function getServerName() {
$path = realpath(__FILE__);
$url = array();
preg_match_all("/\/[a-z0-9-]+(\.[a-z0-9-]+)+/i", $path, $url);
// 4 is minimum requirement for the address (e.g: http://www.in.tv)
if (strlen($url[0][0]) > 4) {
$result = str_replace("/", "", $url[0][0]);
return $result;
}
else
return false;
}
谢谢!
答案 0 :(得分:6)
如果您想要客户端无法设置的服务器名称,请使用$_SERVER['SERVER_NAME']
。它由服务器本身设置,但在某些情况下也可以伪造使用错误,因为Gumbo指出并链接到评论中。
答案 1 :(得分:3)
我认为你指的是
$_SERVER['HTTP_HOST'];
,给定HTTP前缀意味着它来自HTTP标头。
您可能想要使用:
$_SERVER['SERVER_NAME']
由服务器定义,不能通过请求更改?
答案 2 :(得分:3)
这将获得主机名服务器端,但如果您在商业主机(不是自己托管)上运行,我认为这不会有用。
$host = php_uname( 'n' );
如果您正在使用Apache,那么您应该做的是让您的服务器/站点只回答某些名称(否则应该有一个默认不起作用)。您可以使用ServerName
和ServerAlias
指令。
答案 3 :(得分:2)
当然$_SERVER['HTTP_HOST']
可以由客户端修改 - 因为实际上 IT IS 是由客户端发送的。这是http协议的一部分。如果您想获得在apache的vhost配置中定义的主服务器名称,或者您可以按其他人的建议访问$_SERVER['SERVER_NAME']
。
我建议从服务器的文件路径(存储在__FILE__
)中提取域名是不明智的,因为它可能会使您的应用程序无法重定位(它将不再是存储位置不可知的)。
您可以通过使用var_dump($_SERVER)
将其转储到脚本中来查看数组的内容,但请记住,并非所有Web服务器和所有Web服务器设置都暴露相同的环境。这在Web服务器文档中有记录,我认为它部分记录在php在线文档中。
更新/重要提示:正如其他人所指出的,如果为$_SERVER['SERVER_NAME']
配置了apache,则UseCanonicalName off
的内容可能会被欺骗(如果您使用,则可能是默认设置正在使用例如基于Plesk的托管)。因此,实际使用__FILE__
可以解决此问题(如果您的doc根包含主机名)。第一种方法的更大问题是它可以用来向你的应用程序注入任何类型的东西(SQL,JavaScript),因为php程序员通常认为SERVER_NAME
没有用户输入,因此不应用于清理它
答案 4 :(得分:2)
编辑:正如Gumbo所指出的,原始海报可能意味着HTTP_HOST而不是HOST_NAME。否则,我的回答是完全错误的。
HTTP_HOST变量反映了访问者用于访问网站的域名。如果与文件路径没有任何关系!它的值方便地存储在$ _SERVER ['HTTP_HOST']中。有没有其他方法可以得到它?当然,通常有几种方法可以做。例如,当PHP作为Apache模块运行时,这可以工作。
<?php
$request_headers = apache_request_headers();
echo $request_headers['Host'];
?>
问题是:为什么有人想做这样的事情?为什么用一种奇怪的解决方法替换可靠的标准方法,最终从同一个地方获取相同的数据?
您担心HTTP请求会更改$ _SERVER ['HTTP_HOST']。当然是:它就是它的来源。浏览器必须指定它想要访问的站点(这是基于名称的虚拟主机的基础),如果它发送了一个流氓值,那么它就不会到达该站点。
答案 5 :(得分:1)
你没有。这是$ _SERVER变量的目的。如果您想从路径中获取HOST_NAME,则必须先从$ _SERVER ['HTTP_HOST']
获取PATH