2008-11-09 56 views
108

我需要构建一个函数来解析URL中的域名。从PHP解析域名在PHP中

所以,用

http://google.com/dhasjkdas/sadsdds/sdda/sdads.html

http://www.google.com/dhasjkdas/sadsdds/sdda/sdads.html

它应该返回google.com

http://google.co.uk/dhasjkdas/sadsdds/sdda/sdads.html

它应该返回google.co.uk

+15

-1:没有打扰看手册。 – 2012-01-11 10:25:10

+1

看到这一个:http://stackoverflow.com/questions/288810/get-the-subdomain-from-a-url/14688913#14688913 – 2013-02-04 14:41:05

+7

@LightnessRacesinOrbit这不仅仅是“看手册”。 PHP的`parse_url()`返回_host_,而不是_domain_。 – MrWhite 2016-04-25 14:45:00

回答

215

退房parse_url()

$url = 'http://google.com/dhasjkdas/sadsdds/sdda/sdads.html'; 
$parse = parse_url($url); 
echo $parse['host']; // prints 'google.com' 

parse_url不处理实在太差了错位的网址非常好,但是是好的,如果你普遍预期体面的URL。

+24

parse_url()不做的一件事是只返回域。如果您添加www.google.com或www.google.co.uk,它也会返回主机。对此有何建议? – 2008-12-30 00:40:49

+1

@Crad,http://stackoverflow.com/questions/8272805/how-to-handle-mozillas-top-domain-name-list-with-php – ilhan 2011-11-25 21:22:22

+6

`parse_url`不处理子域,但是Purl的确如下:https: //github.com/jwage/purl – Damien 2013-01-18 11:48:40

19

http://us3.php.net/manual/en/function.parse-url.php#93983

一些奇怪的原因,parse_url 返回主机(例如:example.com)作为 当没有方案中 输入URL提供的路径。所以我写了一个快速 函数来获得真正的主机:

function getHost($Address) { 
    $parseUrl = parse_url(trim($Address)); 
    return trim($parseUrl['host'] ? $parseUrl['host'] : array_shift(explode('/', $parseUrl['path'], 2))); 
} 

getHost("example.com"); // Gives example.com 
getHost("http://example.com"); // Gives example.com 
getHost("www.example.com"); // Gives www.example.com 
getHost("http://example.com/xyz"); // Gives example.com 
3

这里是我所做的代码,100%只找到域名,因为它需要mozilla子域来解释。只有你必须检查的是你如何缓存该文件,所以你不要每次都查询mozilla。

由于一些奇怪的原因,像co.uk这样的域名不在列表中,所以你必须做一些黑客攻击并手动添加它们。它不是最干净的解决方案,但我希望它可以帮助某人。

//===================================================== 
static function domain($url) 
{ 
    $slds = ""; 
    $url = strtolower($url); 

      $address = 'http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1'; 
    if(!$subtlds = @kohana::cache('subtlds', null, 60)) 
    { 
     $content = file($address); 
     foreach($content as $num => $line) 
     { 
      $line = trim($line); 
      if($line == '') continue; 
      if(@substr($line[0], 0, 2) == '/') continue; 
      $line = @preg_replace("/[^a-zA-Z0-9\.]/", '', $line); 
      if($line == '') continue; //$line = '.'.$line; 
      if(@$line[0] == '.') $line = substr($line, 1); 
      if(!strstr($line, '.')) continue; 
      $subtlds[] = $line; 
      //echo "{$num}: '{$line}'"; echo "<br>"; 
     } 
     $subtlds = array_merge(Array(
      'co.uk', 'me.uk', 'net.uk', 'org.uk', 'sch.uk', 'ac.uk', 
      'gov.uk', 'nhs.uk', 'police.uk', 'mod.uk', 'asn.au', 'com.au', 
      'net.au', 'id.au', 'org.au', 'edu.au', 'gov.au', 'csiro.au', 
      ),$subtlds); 

     $subtlds = array_unique($subtlds); 
     //echo var_dump($subtlds); 
     @kohana::cache('subtlds', $subtlds); 
    } 


    preg_match('/^(http:[\/]{2,})?([^\/]+)/i', $url, $matches); 
    //preg_match("/^(http:\/\/|https:\/\/|)[a-zA-Z-]([^\/]+)/i", $url, $matches); 
    $host = @$matches[2]; 
    //echo var_dump($matches); 

    preg_match("/[^\.\/]+\.[^\.\/]+$/", $host, $matches); 
    foreach($subtlds as $sub) 
    { 
     if (preg_match("/{$sub}$/", $host, $xyz)) 
     preg_match("/[^\.\/]+\.[^\.\/]+\.[^\.\/]+$/", $host, $matches); 
    } 

    return @$matches[0]; 
} 
9

这是为了工作,100%似乎没有削减对我的代码,我没有打补丁的例子一点点,但发现这是没有帮助的代码,并与它的问题。所以我将它改为了几个函数(为了节省从mozilla始终询问的列表,并删除了cahce系统)。这已经通过一组1000个URL进行了测试,似乎工作。

function domain($url) 
{ 
    global $subtlds; 
    $slds = ""; 
    $url = strtolower($url); 

    $host = parse_url('http://'.$url,PHP_URL_HOST); 

    preg_match("/[^\.\/]+\.[^\.\/]+$/", $host, $matches); 
    foreach($subtlds as $sub){ 
     if (preg_match('/\.'.preg_quote($sub).'$/', $host, $xyz)){ 
      preg_match("/[^\.\/]+\.[^\.\/]+\.[^\.\/]+$/", $host, $matches); 
     } 
    } 

    return @$matches[0]; 
} 

function get_tlds(){ 
    $address = 'http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1'; 
    $content = file($address); 
    foreach($content as $num => $line){ 
      $line = trim($line); 
      if($line == '') continue; 
      if(@substr($line[0], 0, 2) == '/') continue; 
      $line = @preg_replace("/[^a-zA-Z0-9\.]/", '', $line); 
      if($line == '') continue; //$line = '.'.$line; 
      if(@$line[0] == '.') $line = substr($line, 1); 
      if(!strstr($line, '.')) continue; 
      $subtlds[] = $line; 
      //echo "{$num}: '{$line}'"; echo "<br>"; 
    } 

    $subtlds = array_merge(array(
      'co.uk', 'me.uk', 'net.uk', 'org.uk', 'sch.uk', 'ac.uk', 
      'gov.uk', 'nhs.uk', 'police.uk', 'mod.uk', 'asn.au', 'com.au', 
      'net.au', 'id.au', 'org.au', 'edu.au', 'gov.au', 'csiro.au' 
      ),$subtlds); 

    $subtlds = array_unique($subtlds); 

    return $subtlds;  
} 

然后使用它像

$subtlds = get_tlds(); 
echo domain('www.example.com') //outputs: exmaple.com 
echo domain('www.example.uk.com') //outputs: exmaple.uk.com 
echo domain('www.example.fr') //outputs: exmaple.fr 

我知道我应该把这个变成一个类,但没有时间。

1

parse_url不适合我。它只返回了路径。切换到基本使用php5.3 +:

$url = str_replace('http://', '', strtolower($s->website)); 
if (strpos($url, '/')) $url = strstr($url, '/', true); 
-1

如果输入的URL不是全部垃圾,这通常会工作得很好。它删除子域。

$host = parse_url($Row->url, PHP_URL_HOST); 
$parts = explode('.', $host); 
$parts = array_reverse($parts); 
$domain = $parts[1].'.'.$parts[0]; 

输入:http://www2.website.com:8080/some/file/structure?some=parameters

输出:website.com

0

这里我的基于上述答案检索器。

  1. 类实现(我喜欢的OBJ :)
  2. 它使用Curl所以我们可以使用需要HTTP认证
  3. 属于起始URL域
  4. 只抓取链接它打印的HTTP头响应代码(可以用于检查上一个站点的问题)

爬行类代码

class crawler 
{ 
    protected $_url; 
    protected $_depth; 
    protected $_host; 

    public function __construct($url, $depth = 5) 
    { 
     $this->_url = $url; 
     $this->_depth = $depth; 
     $parse = parse_url($url); 
     $this->_host = $parse['host']; 
    } 

    public function run() 
    { 
     $this->crawl_page($this->_url, $this->_depth = 5); 
    } 

    public function crawl_page($url, $depth = 5) 
    { 
     static $seen = array(); 
     if (isset($seen[$url]) || $depth === 0) { 
      return; 
     } 
     $seen[$url] = true; 
     list($content, $httpcode) = $this->getContent($url); 

     $dom = new DOMDocument('1.0'); 
     @$dom->loadHTML($content); 
     $this->processAnchors($dom, $url, $depth); 

     ob_end_flush(); 
     echo "CODE::$httpcode, URL::$url <br>"; 
     ob_start(); 
     flush(); 
     // echo "URL:", $url, PHP_EOL, "CONTENT:", PHP_EOL, $dom->saveHTML(), PHP_EOL, PHP_EOL; 
    } 

    public function processAnchors($dom, $url, $depth) 
    { 
     $anchors = $dom->getElementsByTagName('a'); 
     foreach ($anchors as $element) { 
      $href = $element->getAttribute('href'); 
      if (0 !== strpos($href, 'http')) { 
       $path = '/' . ltrim($href, '/'); 
       if (extension_loaded('http')) { 
        $href = http_build_url($url, array('path' => $path)); 
       } else { 
        $parts = parse_url($url); 
        $href = $parts['scheme'] . '://'; 
        if (isset($parts['user']) && isset($parts['pass'])) { 
         $href .= $parts['user'] . ':' . $parts['pass'] . '@'; 
        } 
        $href .= $parts['host']; 
        if (isset($parts['port'])) { 
         $href .= ':' . $parts['port']; 
        } 
        $href .= $path; 
       } 
      } 
      // Crawl only link that belongs to the start domain 
      if (strpos($href, $this->_host) !== false) 
       $this->crawl_page($href, $depth - 1); 
     } 
    } 

    public function getContent($url) 
    { 
     $handle = curl_init($url); 
     curl_setopt($handle, CURLOPT_RETURNTRANSFER, TRUE); 

     /* Get the HTML or whatever is linked in $url. */ 
     $response = curl_exec($handle); 

     /* Check for 404 (file not found). */ 
     $httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE); 
     if ($httpCode == 404) { 
      /* Handle 404 here. */ 
     } 

     curl_close($handle); 
     return array($response, $httpCode); 
    } 
} 

// USAGE 
$startURL = 'http://YOUR_START_ULR'; 
$depth = 2; 
$crawler = new crawler($startURL, $depth); 
$crawler->run(); 
2

您可以通过PHP_URL_HOST到parse_url功能作为第二个参数

$url = 'http://google.com/dhasjkdas/sadsdds/sdda/sdads.html'; 
$host = parse_url($url, PHP_URL_HOST); 
print $host; // prints 'google.com' 
1

我已经编辑为你:

function getHost($Address) { 
    $parseUrl = parse_url(trim($Address)); 
    $host = trim($parseUrl['host'] ? $parseUrl['host'] : array_shift(explode('/', $parseUrl['path'], 2))); 

    $parts = explode('.', $host); 
    $num_parts = count($parts); 

    if ($parts[0] == "www") { 
     for ($i=1; $i < $num_parts; $i++) { 
      $h .= $parts[$i] . '.'; 
     } 
    }else { 
     for ($i=0; $i < $num_parts; $i++) { 
      $h .= $parts[$i] . '.'; 
     } 
    } 
    return substr($h,0,-1); 
} 

所有类型的网址(www.domain.ltd,sub1.subn.domain.ltd将导致:domain.ltd。

2
$domain = parse_url($url, PHP_URL_HOST); 
echo implode('.', array_slice(explode('.', $domain), -2, 2)) 
7
function get_domain($url = SITE_URL) 
{ 
    preg_match("/[a-z0-9\-]{1,63}\.[a-z\.]{2,6}$/", parse_url($url, PHP_URL_HOST), $_domain_tld); 
    return $_domain_tld[0]; 
} 

get_domain('http://www.cdl.gr'); //cdl.gr 
get_domain('http://cdl.gr'); //cdl.gr 
get_domain('http://www2.cdl.gr'); //cdl.gr 
-5

像下面只需使用...

<?php 
    echo $_SERVER['SERVER_NAME']; 
?> 
-1

结合worldofjr阿利克斯阿克塞尔成一个小的功能,将处理大多数使用情况的答案:

function get_url_hostname($url) { 

    $parse = parse_url($url); 
    return str_ireplace('www.', '', $parse['host']); 

} 

get_url_hostname('http://www.google.com/example/path/file.html'); // google.com 
4

如果你想从字符串http://google.com/dhasjkdas/sadsdds/sdda/sdads.html中提取主机,使用parse_url()是可以接受的解决方案。

但是,如果你想提取域或其部分,你需要使用Public Suffix List包。是的,你可以使用字符串函数arround parse_url(),但它有时会产生不正确的结果。

我建议TLDExtract域解析,这里是显示DIFF示例代码:

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

# For 'http://google.com/dhasjkdas/sadsdds/sdda/sdads.html' 

$url = 'http://google.com/dhasjkdas/sadsdds/sdda/sdads.html'; 

parse_url($url, PHP_URL_HOST); // will return google.com 

$result = $extract->parse($url); 
$result->getFullHost(); // will return 'google.com' 
$result->getRegistrableDomain(); // will return 'google.com' 
$result->getSuffix(); // will return 'com' 

# For 'http://search.google.com/dhasjkdas/sadsdds/sdda/sdads.html' 

$url = 'http://search.google.com/dhasjkdas/sadsdds/sdda/sdads.html'; 

parse_url($url, PHP_URL_HOST); // will return 'search.google.com' 

$result = $extract->parse($url); 
$result->getFullHost(); // will return 'search.google.com' 
$result->getRegistrableDomain(); // will return 'google.com' 
0

我加入这个答案晚,因为这是弹出在谷歌大部分的答案...

您可以使用PHP来...

$url = "www.google.co.uk"; 
$host = parse_url($url, PHP_URL_HOST); 
// $host == "www.google.co.uk" 

主机但不是私人领域到主机指的是哪个。 (例www.google.co.uk是主机,但google.co.uk是私人领域)

抢私人领域,你必须需要知道公共后缀的列表中哪一个可以注册的私人领地。这个列表恰好由Mozilla在https://publicsuffix.org/

策划当下面的代码在公共后缀数组已经创建时工作。只需拨打

$domain = get_private_domain("www.google.co.uk"); 

与其余代码...

// find some way to parse the above list of public suffix 
// then add them to a PHP array 
$suffix = [... all valid public suffix ...]; 

function get_public_suffix($host) { 
    $parts = split("\.", $host); 
    while (count($parts) > 0) { 
    if (is_public_suffix(join(".", $parts))) 
     return join(".", $parts); 

    array_shift($parts); 
    } 

    return false; 
} 

function is_public_suffix($host) { 
    global $suffix; 
    return isset($suffix[$host]); 
} 

function get_private_domain($host) { 
    $public = get_public_suffix($host); 
    $public_parts = split("\.", $public); 
    $all_parts = split("\.", $host); 

    $private = []; 

    for ($x = 0; $x < count($public_parts); ++$x) 
    $private[] = array_pop($all_parts); 

    if (count($all_parts) > 0) 
    $private[] = array_pop($all_parts); 

    return join(".", array_reverse($private)); 
} 
2

我发现,@ philfreo的解决方案(从php.net引用)是颇能获得良好的效果,但在某些情况下,显示php的“通知”和“严格标准”消息。这里是这个代码的固定版本。

function getHost($url) { 
    $parseUrl = parse_url(trim($url)); 
    if(isset($parseUrl['host'])) 
    { 
     $host = $parseUrl['host']; 
    } 
    else 
    { 
     $path = explode('/', $parseUrl['path']); 
     $host = $path[0]; 
    } 
    return trim($host); 
} 

echo getHost("http://example.com/anything.html");   // example.com 
echo getHost("http://www.example.net/directory/post.php"); // www.example.net 
echo getHost("https://example.co.uk");      // example.co.uk 
echo getHost("www.example.net");       // example.net 
echo getHost("subdomain.example.net/anything");    // subdomain.example.net 
echo getHost("example.net");        // example.net