PHP HTTP_HOST子域提取,假设子域是通配符并包含多个'。'

时间:2010-08-05 12:58:02

标签: php subdomain wildcard-subdomain http-host

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

例如,请使用以下HTTP_HOST值以及需要匹配的内容。

  • www.buggedcom.co.uk
    • 子域名:www
    • 域名:buggedcom.co.uk
    • TLD:co.uk
  • www.buggedcom.com
    • 子域名:www
    • 域名:buggedcom.com
    • TLD:com
  • test.buggedcom.co.uk
    • 子域名:test
    • 域名:buggedcom.co.uk
    • TLD:co.uk
  • test.buggedcom.com
    • 子域名:test
    • 域名:buggedcom.com
    • TLD:com
  • multi.sub.test.buggedcom.co.uk
    • 子域名:multi.sub.test
    • 域名:buggedcom.co.uk
    • TLD:co.uk
  • multi.sub.test.buggedcom.com
    • 子域名:multi.sub.test
    • 域名:buggedcom.com
    • TLD: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可以将子域追加为get param吗?

4 个答案:

答案 0 :(得分:1)

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

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

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

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

当然TLD就像.UK的行为可能与co.uk不同 呃..这不是那么容易......

答案 1 :(得分:1)

我认为那些尝试做同样事情的人可以更好地处理这个问题...在PHP文档的注释中有一堆更好的URL解析函数可用于parse_url函数: http://www.php.net/manual/en/function.parse-url.php

答案 2 :(得分: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   
}

答案 3 :(得分:0)

不要挑剔,但从技术上讲,.co.uk是一个二级域名。

在这种情况下,

.uk是“国家/地区代码顶级域名”,而.co是由英国定义的“商业用途”。

这可能不会回答你的问题。

维基百科有一个漂亮的complete list of TLD's,你可以看到它们只包含1个“点”,后跟1个“字符串”。