检测请求是来自不同域还是子域的最佳方法

时间:2013-03-28 20:10:15

标签: php

我正在构建一个使用子域和自定义域名的应用程序,这些域名位于数据库中供用户使用,因此如果请求来自另一个域,我将从数据库中检查该自定义URL是否确实在那里或何时请求来自子域名,我会检查是否存在。如果是我做我的东西。

考虑一下我正在寻找的一个简单例子:

if(is_user_request())
{
    $url = get_url();
    // assuming that get_url() magically decides whether to output ..
    // a custom domain (http://domain.tld)
    // or a subdomain's first part (eg. "this".domain.tld)
}
else
{
    // otherwise it's not a sub domain nor a custom domain,
    // so we're dealing with our own main site.
}

现在在你开始之前假设因为我有0个代表,我在这里要求“teh代码”。我有一个完全可行的方法,这是:

// hosts
$hosts = explode('.', $_SERVER['HTTP_HOST']);

// if there is a subdomain and that's under our $sitename
if(!empty($hosts[1]) AND $hosts[1] === Config::get('domain_mid_name'))
{
    $url = $hosts[0];
    $url_custom = false;
}

 // if there is no subdomain, but the domain is our $sitename
 elseif(!empty($hosts[0]) AND $hosts[0] === Config::get('domain_mid_name') AND !empty($hosts[1]) AND $hosts[1] !== Config::get('domain_mid_name'))
    {
    $url = false;
    $url_custom = false;
}

// otherwise it's most likely that the request
// came from a entirely different domain name.
// which means it's probably $custom_site
else
{
    $url = false;
    $url_custom = implode('.', $hosts);
}

if($url)
{
    return $url;
}

if($url_custom)
{
    return $url_custom;
}

但是,我确信有更好的方法可以做到这一点。因为首先,HTTP_HOST不包含'http://',所以我需要手动添加它,我很确定这整个if,否则只是一个矫枉过正。所以,比我聪明的人,请赐教。

哦,不,我没有预定义的子域名。我设置了一个简单的通配符* .domain.tld,所以所有子域都转到主脚本。我只是这样说,因为在我搜索解决方案时,我发现许多答案建议手动创建一个子域,这与我要求的内容甚至没有关联,所以让我们跳过这个主题。

2 个答案:

答案 0 :(得分:2)

$_SERVER['HTTP_HOST']是正确的方法,除非您想将不同的参数从Web服务器传递到PHP。

至于协议,请注意请求协议应由$_SERVER['HTTPS']确定,而不是假定为http

要提取子域,您可以使用array_shift然后运行

查看
$subdomain = array_shift(explode('.', $_SERVER['HTTP_HOST']));

但一般来说,你应该怎么做。

答案 1 :(得分:1)

如前所述,$_SERVER['HTTP_HOST']是可行的方法。

但是您的代码中存在错误。您假设发送的主机名由2或3个组件组成,但您无法确定。你至少应该检查count($hosts)

如果您通过示例将domain.tld用于自己的网站,那么您最好首先检查是否已发送domain.tld(您快速返回页面);然后查看是否substr($_SERVER['HTTP_HOST']...,-11)==='.domain.tld',如果是,返回子网站(适用于任何级别的子域,仍然很快);否则错误恢复,因为已将完全外来域路由到您。需要注意的关键是,层次结构顶部的域匹配意味着匹配右对齐的主机名字符串:

        .domain.tld | subsite-pattern
   sub12.domain.tld | MATCH
   sub12.dumain.tld | NO MATCH
    sub12domain.tld | NO MATCH