1

我正在尝试从 HTTP_HOST 值中提取子域。但是我偶然发现了一个问题,如果子域中有多个点,则无法正确匹配。鉴于这是一个在多个不同域上运行的脚本,并且它可以有无限数量的点,并且 tld 可以是 1 或 2 部分(以及任何长度) - 是否有正确匹配子域的实用方法,域和所有情况下的tld?

因此,例如采用以下 HTTP_HOST 值以及需要匹配的值。

  • www.buggedcom.co.uk
    • 子域名:www
    • 域名:buggedcom.co.uk
    • 顶级域名:co.uk
  • www.buggedcom.com
    • 子域名:www
    • 域名:buggedcom.com
    • 顶级域名:com
  • test.buggedcom.co.uk
    • 子域:测试
    • 域名:buggedcom.co.uk
    • 顶级域名:co.uk
  • test.buggedcom.com
    • 子域:测试
    • 域名:buggedcom.com
    • 顶级域名:com
  • multi.sub.test.buggedcom.co.uk
    • 子域:multi.sub.test
    • 域名:buggedcom.co.uk
    • 顶级域名:co.uk
  • multi.sub.test.buggedcom.com
    • 子域:multi.sub.test
    • 域名:buggedcom.com
    • 顶级域名:com

我假设完成此操作的唯一方法是加载 tld 列表,这可能让我真的不想这样做,因为这是在脚本的开头,并且确实需要像那样繁重的工作。

以下是当前代码。

define('HOST', isset($_SERVER['HTTP_HOST']) === true ? $_SERVER['HTTP_HOST'] : (isset($_SERVER['SERVER_ADDR']) === true ? $_SERVER['SERVER_ADDR'] : $_SERVER['SERVER_NAME']));
$domain_parts = explode('.', HOST); 
$domain_parts_count = count($domain_parts);
if($domain_parts_count > 1)
{   
    $sub_parts = array_splice($domain_parts, 0, $domain_parts_count-3);
    define('SUBDOMAIN', implode('.', $sub_parts));
    unset($sub_parts);
}
else
{
    define('SUBDOMAIN', '');
}
define('DOMAIN', implode('.', $domain_parts));
var_dump($domain_parts, SUBDOMAIN, DOMAIN);exit;

只是认为 mod_rewrite 可以将子域作为获取参数附加吗?

4

4 回答 4

1

首先,我会在斜杠上爆炸(并使用数组中的第一个索引),以确保字符串以 TLD 结尾。

然后我会用 preg_replace 剪掉它。无论 tld 类型如何,此 rexexp 都匹配域+tld。但是请注意,这会给 2 和 3 个字母的域带来问题。但它应该推动正确的方向......

[a-zA-Z0-9]+\.(([a-zA-Z]{2,6})|([a-zA-Z]{2,3}\.[a-zA-Z]{2,3}))$

编辑:正如所指出的:.museum 也是可能的,因此编辑了 TLD 部分中的第一个模式....

当然,TLD 之类的 .UK 的行为可能与 co.uk 不同,呃……这并不容易……

于 2010-08-05T13:15:14.000 回答
1

我认为解决方案最好由那些试图做同样事情的人处理......在 PHP 文档的注释中有一堆更好的 URL 解析函数,用于 parse_url 函数可能会更好: http://www.php。网络/手册/en/function.parse-url.php

于 2011-08-13T02:47:15.753 回答
0

使用 preg_match,您可以一次性提取子域和 tld 部分,如下所示:

function get_domain_parts($domain) {
    $parts = array();
    $pattern = "/(.*)\.buggedcom\.(.*)/";
    if (preg_match($pattern, $domain, $parts) == 1) {
        return array($parts[1], $parts[2]);
    } else {
        return FALSE;
    }
}

$result = get_domain_parts("multi.sub.test.buggedcom.co.uk");
if ($result) {
    echo($result[0] . " and " . $result[1]); // multi.sub.test and co.uk   
}
于 2010-08-05T13:12:32.010 回答
0

不要吹毛求疵,但从技术上讲.co.uk是二级域。

.uk在这种情况下是“国家代码顶级域”,并且.co是由英国定义的“商业用途”。

不过,这可能无法回答您的问题。

维基百科有一个非常完整的顶级域名列表,你可以看到它们只包含 1 个“点”,后跟 1 个“字符串”。

于 2010-08-05T13:18:12.267 回答