如何在PHP中获得真实的主机或服务器名

如何在PHP中获得真实的主机或服务器名,php,Php,如何在PHP中不使用$\u SERVER['SERVER\u name']来获得真正的主机名?还有其他更可靠的方法吗 我创建了一个函数,它从域的路径获取主机名 我希望避免使用$\u SERVER['SERVER\u NAME']变量,因为它可以通过在HTTP请求中发送修改的头来伪造 这是我当前的实现(如果路径中有实际的域名,则可以使用此方法。例如:/vhosts/website.com/public_html): 谢谢 如果需要客户端无法设置的服务器名称,请使用$\u server['serve

如何在PHP中不使用$\u SERVER['SERVER\u name']来获得真正的主机名?还有其他更可靠的方法吗

我创建了一个函数,它从域的路径获取主机名

我希望避免使用$\u SERVER['SERVER\u NAME']变量,因为它可以通过在HTTP请求中发送修改的头来伪造

这是我当前的实现(如果路径中有实际的域名,则可以使用此方法。例如:/vhosts/website.com/public_html):


谢谢

如果需要客户端无法设置的服务器名称,请使用
$\u server['server\u name']
。它是由服务器本身设置的,但在某些情况下也可以使用bug进行伪造,正如Gumbo指出的,并在评论中链接到。

我认为您指的是

$_SERVER['HTTP_HOST'];
给定HTTP前缀意味着它来自HTTP头

您可能需要使用:

$_SERVER['SERVER_NAME']

它是由服务器定义的,不能通过请求进行更改?

这将获得服务器端的主机名,但是如果您在商业主机上运行(不是自己托管),我认为这不会有多大用处

$host = php_uname( 'n' );

如果您使用的是Apache,那么您应该做的是使您的服务器/站点只对某些名称进行应答(否则应该有一个默认名称,该名称不起多大作用)。您可以使用
ServerName
ServerAlias
指令进行操作。

您不需要。这就是$u服务器变量的用途。如果要从路径获取主机名,必须首先从$\u服务器['HTTP\u HOST']

获取路径。当然,
$\u服务器['HTTP\u HOST']
可以由客户端修改,因为实际上它是由客户端发送的。这是http协议的一部分。如果您想获得apache vhost配置中定义的主服务器名称,或其他人建议的任何可以访问的
$\u server['server\u name']

我建议从服务器的文件路径(存储在
\uuuuu file\uuuu
中)提取域名是不明智的,因为它可能会使您的应用程序无法重新定位(它将不再是存储位置不可知的)

您可以通过使用
var\u dump($\u SERVER)
在脚本中转储数组来查看数组的内容,但请记住,并非所有web服务器和所有web服务器设置都公开相同的环境。这在web服务器文档中有记录,我认为php在线文档中也有部分记录

更新/重要注意事项:正如其他人指出的那样,如果apache配置为
UseCononicalName off
(如果您使用基于Plesk的主机,这可能是默认设置),则
$\u SERVER['SERVER\u NAME']
的内容可能会被欺骗。因此,实际使用
\uuu文件可以解决这个问题(如果您的文档根包含主机名)。第一种方法更大的问题是,它可以用于向应用程序中注入任何类型的内容(SQL、JavaScript),因为php程序员通常认为,
SERVER\u NAME
不是用户输入,因此不会对其进行消毒,最初的海报可能是指HTTP_主机,而不是主机名。否则,我的答案显然是错误的

HTTP_主机变量反映访问者用于访问站点的域名。如果与文件路径无关!它的值可以方便地存储在$_服务器['HTTP_HOST']中。还有别的办法吗?当然,做事情通常有几种方法。例如,当PHP作为Apache模块运行时,这就起作用了

<?php

$request_headers = apache_request_headers();
echo $request_headers['Host'];

?>

问题是:为什么会有人想做这样的事?为什么要用一种古怪的解决方法来取代可靠的标准方法,最终从同一个地方获取同一段数据


您担心$\u服务器['HTTP\u HOST']会被HTTP请求更改。当然是这样:这就是它的来源。浏览器必须指定它要访问的站点(这是基于名称的虚拟主机的基础),如果它发送了一个恶意值,那么它就无法访问该站点。

如果你只使用主机名的白名单,你将永远不会被注入更多可能他不知道如何正确地表达他的问题。帮助新手并解释他在提供的环境和HTTP协议中误解了什么,而不是否决他的问题,这将是一件好事。我来解决这个问题。问题是,他说的话有一半我不明白,只能对他所说的进行推断。我只能假设‘PATH’是‘SCRIPT_PATH’的意思,我不知道他说的是‘HTTP_HOST’还是‘SERVER_NAME’。似乎很难相信他能写一个脚本,却不知道他在使用哪些变量。@Chacha102是的,我知道,我从我的同事那里反复听到同样的问题…;-)我刚刚发布了一个较长的答案,希望下一个“信息寻求者”能更容易地找到它。希望最后消失?;-)嗯,nvm。我不会编辑它,因为他不知道他说的是什么变量,因此我不能可靠地解决这个问题。@minnur请解决你原来的问题。。。(美元服务器的散列索引似乎不正确)谢谢大家。这就是我想知道的。谢谢你的回答!我将使用$path=realpath(文件);事实上,它可以被客户端操纵(请参阅)。@Gumbo:那是一个bug。不管它是否仍然存在,我都不知道(那篇博客已经有将近4年的历史了)@R.Bemrose:它仍然存在(PHP5.3.0)。@Gumbo:很高兴知道!我会把它添加到我的答案中。有些事情永远不会改变…;-)但我不知道这是否真的是一只虫子。可能这种行为是故意的。没有
$\u服务器['HOST\u NAME']
;这是
$\u服务器['HTTP\u HOST']
。OP的主机可能存在的主要问题是,它是一个受管理的标准apache/plesk/which安装
<?php

$request_headers = apache_request_headers();
echo $request_headers['Host'];

?>