2008-12-30 30 views
12

PHP的parse_url()有一个主机字段,其中包括完整的主机。我正在寻找最可靠(且成本最低)的方式来仅返回域名和TLD。去哪里PHP parse_url()不 - 只分析域

给出的例子:

我只在寻找google.comgoogle.co.uk。我考虑过一个有效的顶级域名(TLD)/后缀表,只允许这些和一个单词。你会以任何其他方式做到吗?有没有人知道这种事情的预先装罐的有效REGEX?

+0

你已经做出了判断前面那个我不知道将举行不够好,那是你可以告诉部分的主机是感兴趣的领域,它是真的是顶级域名? – 2008-12-30 01:29:35

+0

例如,如果只查看标准域名,几乎任何dyndns域名似乎都会被阻止。要阻止来自www.mysite.isa-geek.org域名的垃圾邮件,或者只是mysite.isa-geek.org,您是否会关心是否阻止了所有的isa-geek.org? – 2008-12-30 01:30:55

+0

是的,在这种情况下,我会很好地阻止isa-geek.org。我最关心的是foo。[suffix]其中[suffix]是标准后缀的tld或组合。 tld(co.uk) – 2008-12-30 01:43:49

回答

17

这样的事情呢?

function getDomain($url) { 
    $pieces = parse_url($url); 
    $domain = isset($pieces['host']) ? $pieces['host'] : ''; 
    if (preg_match('/(?P<domain>[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$/i', $domain, $regs)) { 
    return $regs['domain']; 
    } 
    return false; 
} 

将使用经典parse_url提取域名,然后寻找一个有效的域名没有任何的子域(WWW是一个子域)。不适用于'localhost'之类的东西。如果它不匹配任何内容,将返回false。

//编辑:

尝试一下用:

echo getDomain('http://www.google.com/test.html') . '<br/>'; 
echo getDomain('https://news.google.co.uk/?id=12345') . '<br/>'; 
echo getDomain('http://my.subdomain.google.com/directory1/page.php?id=abc') . '<br/>'; 
echo getDomain('https://testing.multiple.subdomain.google.co.uk/') . '<br/>'; 
echo getDomain('http://nothingelsethan.com') . '<br/>'; 

它应该返回:

google.com 
google.co.uk 
google.com 
google.co.uk 
nothingelsethan.com 

当然,如果它不它不会返回任何东西通过parse_url,所以请确保它是一个格式正确的网址。

//附录:

参宿是正确的。上述解决方案将在大多数案件中发挥作用,但不一定全部需要维护,以确保它们不是新的顶级域名,例如6个以上的字符等等。提取域的唯一可靠方法是使用维护的列表,如http://publicsuffix.org/。起初更痛苦,但长期更容易和更强大。你需要确保你了解每种方法的优缺点,以及它如何适合你的项目。

0

当然,这取决于您的具体使用情况,但一般来说我不会使用TLD的表查找。新的顶级域名出来了,你通常不想在任何地方维护它们。请问我的[email protected]因短视而被拒绝。

如果我知道你为什么不需要www,我想我可以帮助更好?你需要它的电子邮件?您可以在这种情况下查询MX记录以验证它(最终)是否接受邮件。

您也可以找到有关处理DNS记录的PHP函数的帮助,以了解更多关于它们的信息,例如,参见http://php.net/dns_get_record

0

只是一个证明,假设允许的tlds被记忆成一个散列。代码可以缩短很多。

<?php 
    $urlCompoments=parse_url($theUrl); 
    $chunk=explode('.',$urlComponents['host']); 

    $tldIndex = count($chunk-1); // assume last chunk is tld 
    $maxTldLen = 2; // assuming a tld can be in the form .com or .co.uk 
    $cursor=1; 
    $found=false; 
    while(($cursor<=$maxTldLen) or $found) { 
     $tls = implode('.',array_slice($chunk, -$cursor)); 
     $found=isset($tldSuffixesAllowed[$tld]); 
     $cursor++; 
    } 
    if ($found){ 
     $tld=implode('.',array_slice($chunk, -$cursor)); 
    } else { 
     // domain not recognized, do wathever you want 
    } 
?> 
-2

有一个非常简单的解决办法是:

function get_domain($url) { 
    $pieces = parse_url($url); 
    return array_pop(explode('.', $pieces['host'], 2)); 
} 

当然这是否行得通呢?

3

Python的tldextract模块http://w-shadow.com/blog/2012/08/28/tldextract还有一个非常好的端口 - 这超越了parse_url,并且允许你在没有子域的情况下实际获取域/ tld。

从模块网站:

$components = tldextract('http://www.bbc.co.uk'); 
echo $components->subdomain; // www 
echo $components->domain; // bbc 
echo $components->tld;  // co.uk 
0

你需要使用Public Suffix List,只有这样,你才能正确提取与二,三级顶级域名(co.uk,a.bg,B域包.bg等)和多级子域。正则表达式,parse_url()或字符串函数永远不会产生绝对正确的结果。

我推荐使用TLD Extract。的代码下面例子:

$extract = new LayerShifter\TLDExtract\Extract(); 

$result = $extract->parse('http://www.google.co.uk/foo'); 
$result->getSubdomain(); // will return (string) 'www' 
$result->getHostname(); // will return (string) 'google' 
$result->getSuffix(); // will return (string) 'co.uk' 
$result->getRegistrableDomain(); // will return (string) 'google.co.uk'