2010-07-09 36 views
13

我需要从URL获取域名。下面的例子都应该返回google.com如何使用PHP从URL获取基本域名?

google.com 
images.google.com 
new.images.google.com 
www.google.com 

同样,以下网址应该都返回google.co.uk

google.co.uk 
images.google.co.uk 
new.images.google.co.uk 
http://www.google.co.uk 

我犹豫使用正则表达式,因为类似domain.com/google.com可以返回不正确的结果。

如何使用PHP获取顶级域名?这需要在所有平台和主机上运行。

+1

这是棘手。对于'google.com',您对TLD和二级域名感兴趣。对于'google.co.uk',您需要TLD以及第二和第三级域名。没有定义的“基本名称”,对于不同的注册商/ TLD,“基本名称”的含义不同。 – deceze 2010-07-09 09:42:06

+1

我非常确定你必须在这里有点长时间的啰嗦,你要求的是吃你的蛋糕并拥有它。如果没有TLD列表,则无法区分co.uk和google.com,它们都是主机名。 – 2010-07-09 09:43:07

+0

我想你们是对的,它不看起来像任何东西都会工作没有很多的代码 – Rohan 2010-07-09 09:46:39

回答

16

你可以这样做:

$urlData = parse_url($url); 

$host = $urlData['host']; 

** **更新

我能想到的最好的办法是将所有顶级域名的映射你想处理,因为某些TLD可能会很棘手(co.uk)。

// you can add more to it if you want 
$urlMap = array('com', 'co.uk'); 

$host = ""; 
$url = "http://www.google.co.uk"; 

$urlData = parse_url($url); 
$hostData = explode('.', $urlData['host']); 
$hostData = array_reverse($hostData); 

if(array_search($hostData[1] . '.' . $hostData[0], $urlMap) !== FALSE) { 
    $host = $hostData[2] . '.' . $hostData[1] . '.' . $hostData[0]; 
} elseif(array_search($hostData[0], $urlMap) !== FALSE) { 
    $host = $hostData[1] . '.' . $hostData[0]; 
} 

echo $host; 
3

尝试使用:http://php.net/manual/en/function.parse-url.php。像这样的东西应该工作:

$urlParts = parse_url($yourUrl); 
$hostParts = explode('.', $urlParts['host']); 
$hostParts = array_reverse($hostParts); 
$host = $hostParts[1] . '.' . $hostParts[0]; 
+1

如果你有这样的事情会破坏:http: //www.google.co.uk - 在这种情况下,它会返回“co.uk”。 – xil3 2010-07-09 09:43:50

+1

确实,获得这种排序的唯一方法是使用TLD列表。 – 2010-07-09 09:49:39

-3

使用此功能:

function getHost($url){ 
    if (strpos($url,"http://")){ 
     $httpurl=$url; 
    } else { 
     $httpurl="http://".$url; 
    } 
    $parse = parse_url($httpurl); 
    $domain=$parse['host']; 

    $portion=explode(".",$domain); 
    $count=sizeof($portion)-1; 
    if ($count>1){ 
     $result=$portion[$count-1].".".$portion[$count]; 
    } else { 
     $result=$domain; 
    } 
    return $result; 
} 

答案例如URL的所有变体。

5

顶级域名和二级域名的长度可能为2个字符,但注册的子域名的长度必须至少为3个字符。

编辑:由于pjv的评论,我了解到澳大利亚域名是一个例外,因为它们允许5个TLD作为SLD(com,net,org,asn,id)例如:somedomain.com.au。我猜com.au是“共享”的国家控制域名。所以,从技术上讲,“com.au”仍然是“基本域”,但这没有用。编辑:有47,952个可能的三字母域名(模式:[a-zA-Z0-9] [a-zA-Z0-9 - ] [a-zA-Z0-9]或36 * 37 * 36)与最常见的8种TLDS(com,org等)相结合,我们有383,616种可能性 - 甚至无需在TLD的整个范围内进行添加。 1个字母和2个字母的域名仍然存在,但不能继续使用。

在google.com

- “Google”对应的“COM”子域

在google.co.uk

- “谷歌”是“CO”,的一个子域这又是一个子域因为“co”也是有效的顶级域名

www.google.com - “www”是“google”的子域,它是一个子域“COM”的

“co.uk”不是一个有效的主机,因为没有有效的域名

与assumpt去在几乎所有情况下,该函数都会返回适当的“basedomain”,而不需要“url map”。

如果你碰巧是罕见的情况之一,也许你可以修改它以满足特定的需求...

编辑:你必须通过域名字符串作为URL与它的协议(http://,ftp://等)或parse_url()不会认为它是一个有效的URL(除非你想修改代码的行为不同)

function basedomain($str = '') 
{ 
    // $str must be passed WITH protocol. ex: http://domain.com 
    $url = @parse_url($str); 
    if (empty($url['host'])) return; 
    $parts = explode('.', $url['host']); 
    $slice = (strlen(reset(array_slice($parts, -2, 1))) == 2) && (count($parts) > 2) ? 3 : 2; 
    return implode('.', array_slice($parts, (0 - $slice), $slice)); 
} 

如果你需要准确运用fopencurl打开这个网址: http://data.iana.org/TLD/tlds-alpha-by-domain.txt

然后读取行到一个数组,并使用该域的部分比较

编辑:允许澳大利亚域:

function au_basedomain($str = '') 
{ 
    // $str must be passed WITH protocol. ex: http://domain.com 
    $url = @parse_url($str); 
    if (empty($url['host'])) return; 
    $parts = explode('.', $url['host']); 
    $slice = (strlen(reset(array_slice($parts, -2, 1))) == 2) && (count($parts) > 2) ? 3 : 2; 
    if (preg_match('/\.(com|net|asn|org|id)\.au$/i', $url['host'])) $slice = 3; 
    return implode('.', array_slice($parts, (0 - $slice), $slice)); 
} 

重要的附加说明:我不使用这个功能来验证域。这是通用代码,我只用它从全局$_SERVER['SERVER_NAME']中提取它所运行的服务器的基本域,以用于各种内部脚本。考虑到我只在美国境内工作过,我从来没有遇到pjv问过的澳大利亚变种。这对于内部使用来说很方便,但是距离完整的域验证过程还有很长的路要走。如果您尝试以这种方式使用它,我建议不要因为与无效域名匹配的可能性太大。

+1

如果您将'strlen()== 2'更改为'<= 3',您将捕获99%的域,将子域保存在本地主机上以及其他内容。这里是我的修订整理:https://gist.github.com/anonymous/fe77c97e632675411c3c – Mahn 2015-05-04 23:00:12

+0

不,修订无法正常工作。它需要是== 2,因为当最后一个部分的下一个是3时,<= 3将匹配 - 我们不想这样做。我们希望它从“www.google.com”或“mail.google.com”返回“google.com”,并且我们希望它从“www.google.co.uk”返回“google.co.uk”或“mail.google.co.uk” – aequalsb 2015-05-15 19:36:35

+0

@Mahn另外,修订中还有许多额外的位 - 不需要的变量赋值和不需要的条件嵌套。更多代码和不良结果 - 您是否彻底测试了您的修订版本? – aequalsb 2015-05-15 19:43:59

0

与xil3混合回答这是我得去检查本地主机以及IP,所以你也可以在开发环境中工作。
您仍然必须定义要使用的TLD。除此之外,一切工作正常。

<?php 
function getTopLevelDomain($url){ 
    $urlData = parse_url($url); 
    $urlHost = isset($urlData['host']) ? $urlData['host'] : ''; 
    $isIP = (bool)ip2long($urlHost); 
    if($isIP){ /** To check if it's ip then return same ip */ 
     return $urlHost; 
    } 
    /** Add/Edit you TLDs here */ 
    $urlMap = array('com', 'com.pk', 'co.uk'); 

    $host = ""; 
    $hostData = explode('.', $urlHost); 
    if(isset($hostData[1])){ /** To check "localhost" because it'll be without any TLDs */ 
     $hostData = array_reverse($hostData); 

     if(array_search($hostData[1] . '.' . $hostData[0], $urlMap) !== FALSE) { 
      $host = $hostData[2] . '.' . $hostData[1] . '.' . $hostData[0]; 
     } elseif(array_search($hostData[0], $urlMap) !== FALSE) { 
      $host = $hostData[1] . '.' . $hostData[0]; 
     } 
     return $host; 
    } 
    return ((isset($hostData[0]) && $hostData[0] != '') ? $hostData[0] : 'error no domain'); /* You can change this error in future */ 
} 
?> 

,你可以使用它像这样

$string = 'http://googl.com.pk'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://googl.com.pk:23'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://googl.com'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://googl.com:23'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://adad.asdasd.googl.com.pk'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://adad.asdasd.googl.com.pk:23'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://adad.asdasd.googl.com'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://adad.asdasd.googl.com:23'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://192.168.0.101:23'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://192.168.0.101'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://localhost'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'https;//'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = ''; 
echo getTopLevelDomain($string) . '<br>'; 

你会得到导致字符串这样

googl.com.pk 
googl.com.pk 
googl.com 
googl.com 
googl.com.pk 
googl.com.pk 
googl.com 
googl.com 
192.168.0.101 
192.168.0.101 
localhost 
error no domain 
error no domain