php 获取当前域

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10717249/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 22:53:06  来源:igfitidea点击:

Get current domain

phpurl

提问by Tony Evyght

I have my site on server

我在服务器上有我的网站

http://www.myserver.uk.com

For this I have two domains,

为此,我有两个域,

http://one.com

and

http://two.com

I would like get with PHP current domain, but if I use $_SERVER['HTTP_HOST']then this show me

我想使用 PHP 当前域,但如果我使用,$_SERVER['HTTP_HOST']那么这会告诉我

myserver.uk.com

instead of:

代替:

one.com or two.com

How can I get the domain, not the server name?

如何获取域,而不是服务器名称?

I have PHP version 5.2.

我有 PHP 5.2 版。

回答by onehalf

Try using this: $_SERVER['SERVER_NAME']

尝试使用这个: $_SERVER['SERVER_NAME']

Or parse

或者解析

$_SERVER['REQUEST_URI']

apache_request_headers()

apache_request_headers()

回答by K. Kilian Lindberg

The best use would be

最好的用途是

echo $_SERVER['HTTP_HOST'];

And it can be used like this:

它可以像这样使用:

if (strpos($_SERVER['HTTP_HOST'], 'banana.com') !== false) {
    echo "Yes this is indeed the banana.com domain";
}

This code below is a good way to see all the variables in $_SERVER in a structured HTML output with your keywords highlighted that halts directly after execution. Since I do sometimes forget which one to use myself - I think this can be nifty.

下面的代码是在结构化 HTML 输出中查看 $_SERVER 中所有变量的好方法,其中突出显示了您的关键字,并在执行后直接停止。因为我有时会忘记自己使用哪个 - 我认为这可能很漂亮。

<?php
    // Change banana.com to the domain you were looking for..
    $wordToHighlight = "banana.com";
    $serverVarHighlighted = str_replace( $wordToHighlight, '<span style=\'background-color:#883399; color: #FFFFFF;\'>'. $wordToHighlight .'</span>',  $_SERVER );
    echo "<pre>";
    print_r($serverVarHighlighted);
    echo "</pre>";
    exit();
?>

回答by Raz0rwire

Using $_SERVER['HTTP_HOST']gets me (subdomain.)maindomain.extension. It seems like the easiest solution to me.

使用$_SERVER['HTTP_HOST']让我(子域。)maindomain.extension。这对我来说似乎是最简单的解决方案。

If you're actually 'redirecting' through an iFrame, you could add a GETparameter which states the domain.

如果您实际上是通过 iFrame 进行“重定向”,则可以添加一个GET参数来说明域。

<iframe src="myserver.uk.com?domain=one.com"/>

And then you could set a session variable that persists this data throughout your application.

然后你可以设置一个会话变量,在整个应用程序中保留这些数据。

回答by wp-overwatch.com

The only secure way of doing this

这样做的唯一安全方法

All of the other answers on this page have security implications that you need to be aware of.

此页面上的所有其他答案都具有您需要注意的安全隐患。

The only guaranteed secure method of retrieving the current domain is to .

Most frameworks take care of storing the domain for you, so you will want to consult the documentation for your particular framework. If you're not using a framework, consider storing the domain in one of the following places:

大多数框架会为您存储域,因此您需要查阅特定框架的文档。如果您不使用框架,请考虑将域存储在以下位置之一:

+----------------------------------------------------+-----------------------------------+
 |   Secure methods of storing the domain   |                Used By                 |
+----------------------------------------------------+-----------------------------------+
 | A config file                                             | Joomla, Drupal/Symfony   |
 | The database                                         | WordPress                          |
 | An environmental variable                     | Laravel                               |
 | A service registry                                    | Kubernetes DNS                |
+----------------------------------------------------+-----------------------------------+

+------------------------------------------------- ---+-----------------------------------+
 | 存储域的安全方法 | 使用人 |
+------------------------------------------------- ---+-----------------------------------+
 | 一个配置文件 | Joomla,Drupal/Symfony |
 | 数据库 | WordPress |
 | 一个环境变量 | 拉拉维尔 |
 | 服务注册 | Kubernetes DNS |
+------------------------------------------------- ---+-----------------------------------+



You can use the following... but they're insecure

您可以使用以下...但它们不安全

Hackers can make these variables output whatever domain they want. This can lead to cache poisoning and barely noticeable phishing attacks.

黑客可以让这些变量输出他们想要的任何域。这可能导致缓存中毒和几乎不明显的网络钓鱼攻击。

$_SERVER['HTTP_HOST']

This gets the domain from the request headers which are open to manipulation by hackers. Same with:

这从对黑客开放的请求头中获取域。同:

$_SERVER['SERVER_NAME']

This one can be made better if the Apache setting usecanonicalnameis turned off; in which case $_SERVER['SERVER_NAME']will no longer be allowed to be populated with arbitrary values and will be secure. This is, however, non-default and not that common of a setup.

如果 Apache 设置usecanonicalname被关闭,这个可以做得更好;在这种情况下,$_SERVER['SERVER_NAME']将不再允许填充任意值并且是安全的。但是,这是非默认设置,并且在设置中并不常见。



In popular systems

在流行的系统中

Below is how you can get the current domain in the following frameworks/systems:

以下是如何在以下框架/系统中获取当前域:

WordPress

WordPress

$urlparts = parse_url(home_url());
$domain = $urlparts['host'];

If you're constructing a URL in WordPress, just use home_urlor site_url, or any of the other URL functions.

如果您在 WordPress 中构建 URL,只需使用home_urlsite_url或任何其他 URL 函数

Laravel

Laravel

request()->getHost()

The request()->getHostfunction is inherited from Symfony, and has been secure since the 2013 CVE-2013-4752was patched.

request()->getHost功能继承自 Symfony,自 2013 CVE-2013-4752修补以来一直是安全的。

Drupal

德鲁巴

The installer does not yet take care of making this secure (issue #2404259). But in Drupal 8 there is documentation you can you can follow at Trusted Host Settingsto secure your Drupal installation after which the following can be used:

安装程序尚未考虑确保安全(问题 #2404259)。但是在 Drupal 8 中,您可以在受信任的主机设置中遵循文档来保护您的 Drupal 安装,然后可以使用以下内容:

\Drupal::request()->getHost();

Other frameworks

其他框架

Feel free to edit this answer to include how to get the current domain in your favorite framework. When doing so, please include a link to the relevant source code or to anything else that would help me verify that the framework is doing things securely.

随意编辑此答案以包括如何在您喜欢的框架中获取当前域。这样做时,请包含指向相关源代码或其他任何可以帮助我验证框架是否安全运行的链接。







Addendum

附录

Exploitation examples:

利用示例:

  1. Cache poisoning can happen if a botnet continuously requests a page using the wrong hosts header. The resulting HTML will then include links to the attackers website where they can phish your users. At first the malicious links will only be sent back to the hacker, but if the hacker does enough requests, the malicious version of the page will end up in your cache where it will be distributed to other users.

  2. A phishing attack can happen if you store links in the database based on the hosts header. For example, let say you store the absolute URL to a user's profiles on a forum. By using the wrong header, a hacker could get anyone who clicks on their profile link to be sent a phishing site.

  3. Password reset poisoning can happen if a hacker uses a malicious hosts header when filling out the password reset form for a different user. That user will then get an email containing a password reset link that leads to a phishing site.

  4. Here are some more malicious examples

  1. 如果僵尸网络使用错误的主机标头持续请求页面,则可能发生缓存中毒。生成的 HTML 将包含指向攻击者网站的链接,他们可以在那里对您的用户进行网络钓鱼。起初恶意链接只会被发送回黑客,但如果黑客做了足够多的请求,页面的恶意版本最终会在您的缓存中分发给其他用户。

  2. 如果您根据主机标头将链接存储在数据库中,则可能会发生网络钓鱼攻击。例如,假设您在论坛上存储用户个人资料的绝对 URL。通过使用错误的标题,黑客可以让任何点击其个人资料链接的人被发送到网络钓鱼站点。

  3. 如果黑客在为其他用户填写密码重置表单时使用恶意主机标头,则可能会发生密码重置中毒。然后,该用户将收到一封电子邮件,其中包含指向网络钓鱼站点的密码重置链接。

  4. 这里有一些更恶意的例子

Additional Caveats and Notes:

其他注意事项和注意事项:

  • When usecanonicalnameis turned off the $_SERVER['SERVER_NAME']is populated with the same header $_SERVER['HTTP_HOST']would have used anyways (plus the port). This is Apache's default setup. If you or devops turns this on then you're okay -- ish -- but do you really want to rely on a separate team, or yourself three years in the future, to keep what would appear to be a minor configuration at a non-default value? Even though this makes things secure, I would caution against relying on this setup.
  • Redhat, however, does turn usecanonical on by default [source].
  • If serverAliasis used in the virtual hosts entry, and the aliased domain is requested, $_SERVER['SERVER_NAME']will not return the current domain, but will return the value of the serverName directive.
  • If the serverName cannot be resolved, the operating system's hostname command is used in its place [source].
  • If the host header is left out, the server will behave as if usecanonical was on [source].
  • Lastly, I just tried exploiting this on my local server, and was unable to spoof the hosts header. I'm not sure if there was an update to Apache that addressed this, or if I was just doing something wrong. Regardless, this header would still be exploitable in environments where virtual hosts are not being used.
  • usecanonicalname关闭时,$_SERVER['SERVER_NAME']会填充相同的标头$_SERVER['HTTP_HOST'](加上端口)。这是 Apache 的默认设置。如果您或 devops 启用此功能,那么您就可以了 - 是的 - 但是您是否真的想依靠一个单独的团队,或者在未来三年内依靠您自己来将看似次要的配置保持在非-默认值?尽管这使事情变得安全,但我会告诫不要依赖此设置。
  • 然而,Redhat 确实默认开启了 usecanonical []。
  • 如果在虚拟主机条目中使用了serverAlias,并且请求了别名域,$_SERVER['SERVER_NAME']则不会返回当前域,但会返回 serverName 指令的值。
  • 如果 serverName 无法解析,则在其位置使用操作系统的 hostname 命令[source]
  • 如果主机头被省略,服务器的行为就像 usecanonical 在[source] 上一样
  • 最后,我只是尝试在我的本地服务器上利用它,但无法欺骗主机标头。我不确定 Apache 是否有更新解决了这个问题,或者我只是做错了什么。无论如何,在不使用虚拟主机的环境中,这个标头仍然可以被利用。

Little Rant:

小吐槽:

     This question received hundreds of thousands of views without a single mention of the security problems at hand! It shouldn't be this way, but just because a Stack Overflow answer is popular, that doesn't mean it is secure.

     这个问题收到了数十万的浏览量,却没有提到手头的安全问题!它不应该是这样,但仅仅因为 Stack Overflow 的答案很受欢迎,这并不意味着它是安全的。





回答by flowfree

Try $_SERVER['SERVER_NAME'].

试试$_SERVER['SERVER_NAME']

Tips: Create a PHP file that calls the function phpinfo()and see the "PHP Variables" section. There are a bunch of useful variables we never think of there.

提示:创建一个调用该函数的 PHP 文件,phpinfo()请参阅“PHP 变量”部分。有一堆我们从未想过的有用变量。

回答by InfiniteStack

I know this might not be entirely on the subject, but in my experience, I find storing WWW-ness of current URL in a variable useful.

我知道这可能不完全是关于这个主题,但根据我的经验,我发现将当前 URL 的 WWW-ness 存储在一个变量中很有用。

Edit:In addition, please see my comment below, to see what this is getting at.

编辑:另外,请看我下面的评论,看看这是什么意思。

This is important when determining whether to dispatch Ajax calls with "www", or without:

这在确定是否使用“www”分派 Ajax 调用时很重要:

$.ajax("url" : "www.site.com/script.php", ...

$.ajax("url" : "site.com/script.php", ...

When dispatching an Ajax call the domain name must match that of in the browser's address bar, otherwise you will have Uncaught SecurityErrorin console.

调度 Ajax 调用时,域名必须与浏览器地址栏中的域名匹配,否则控制台中将出现Uncaught SecurityError

So I came up with this solution to address the issue:

所以我想出了这个解决方案来解决这个问题:

<?php
    substr($_SERVER['SERVER_NAME'], 0, 3) == "www" ? $WWW = true : $WWW = false;

    if ($WWW) {
        /* We have www.example.com */
    } else {
        /* We have example.com */
    }
?>

Then, based on whether $WWW is true, or false run the proper Ajax call.

然后,根据 $WWW 是真还是假,运行正确的 Ajax 调用。

I know this might sound trivial, but this is such a common problem that is easy to trip over.

我知道这可能听起来微不足道,但这是一个很容易绊倒的常见问题。

回答by Manojkiran.A

Everybody is using the parse_urlfunction, but sometimes user may pass the argumet in different format.

每个人都在使用该parse_url功能,但有时用户可能会以不同的格式传递参数。

So as to fix that, I have created the function. Check this out:

为了解决这个问题,我创建了这个函数。看一下这个:

function fixDomainName($url='')
{
    $strToLower = strtolower(trim($url));
    $httpPregReplace = preg_replace('/^http:\/\//i', '', $strToLower);
    $httpsPregReplace = preg_replace('/^https:\/\//i', '', $httpPregReplace);
    $wwwPregReplace = preg_replace('/^www\./i', '', $httpsPregReplace);
    $explodeToArray = explode('/', $wwwPregReplace);
    $finalDomainName = trim($explodeToArray[0]);
    return $finalDomainName;
}

Just pass the URL and get the domain.

只需传递 URL 并获取域。

For example,

例如,

echo fixDomainName('https://stackoverflow.com');

will return the result will be

将返回结果将是

stackoverflow.com

And in some situation:

在某些情况下:

echo fixDomainName('stackoverflow.com/questions/id/slug');

And it will also return stackoverflow.com.

它也会返回stackoverflow.com

回答by Sarkar

$_SERVER['HTTP_HOST'] 

//to get the domain

//获取域

$protocol=strpos(strtolower($_SERVER['SERVER_PROTOCOL']),'https') === FALSE ? 'http' : 'https';
$domainLink=$protocol.'://'.$_SERVER['HTTP_HOST'];

//domain with protocol

//带有协议的域

$url=$protocol.'://'.$_SERVER['HTTP_HOST'].'?'.$_SERVER['QUERY_STRING'];

//protocol,domain,queryString total **As the $_SERVER['SERVER_NAME'] is not reliable for multi domain hosting!

//protocol,domain,queryString total **因为 $_SERVER['SERVER_NAME'] 对于多域托管是不可靠的!

回答by Motion

Simply try:

只需尝试:

echo apache_request_headers()[3];