2008-12-30 33 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'