2014-12-27 139 views
0

我在網上查找(也在這裏)查看從URL獲取域的所有可能功能。我發現 最新的代碼是從這裏開始 - https://gist.github.com/pocesar/5366899PHP從URL獲取域名

  <?php 
      /** 
      * @param string $domain Pass $_SERVER['SERVER_NAME'] here 
      * @param bool $debug 
      * 
      * @debug bool $debug 
      * @return string 
      */ 
      function get_domain($domain, $debug = false) 
      { 
       $original = $domain = strtolower($domain); 

       if (filter_var($domain, FILTER_VALIDATE_IP)) { return $domain; } 

       $debug ? print('<strong style="color:green">&raquo;</strong> Parsing: '.$original) : false; 

       $arr = array_slice(array_filter(explode('.', $domain, 4), function($value){ 
        return $value !== 'www'; 
       }), 0); //rebuild array indexes 

       if (count($arr) > 2) 
       { 
        $count = count($arr); 
        $_sub = explode('.', $count === 4 ? $arr[3] : $arr[2]); 

        $debug ? print(" (parts count: {$count})") : false; 

        if (count($_sub) === 2) // two level TLD 
        { 
         $removed = array_shift($arr); 
         if ($count === 4) // got a subdomain acting as a domain 
         { 
          $removed = array_shift($arr); 
         } 
         $debug ? print("<br>\n" . '[*] Two level TLD: <strong>' . join('.', $_sub) . '</strong> ') : false; 
        } 
        elseif (count($_sub) === 1) // one level TLD 
        { 
         $removed = array_shift($arr); //remove the subdomain 

         if (strlen($_sub[0]) === 2 && $count === 3) // TLD domain must be 2 letters 
         { 
          array_unshift($arr, $removed); 
         } 
         else 
         { 
          // non country TLD according to IANA 
          $tlds = array(
           'aero', 
           'arpa', 
           'asia', 
           'biz', 
           'cat', 
           'com', 
           'coop', 
           'edu', 
           'gov', 
           'info', 
           'jobs', 
           'mil', 
           'mobi', 
           'museum', 
           'name', 
           'net', 
           'org', 
           'post', 
           'pro', 
           'tel', 
           'travel', 
           'xxx', 
          ); 

          if (count($arr) > 2 && in_array($_sub[0], $tlds) !== false) //special TLD don't have a country 
          { 
           array_shift($arr); 
          } 
         } 
         $debug ? print("<br>\n" .'[*] One level TLD: <strong>'.join('.', $_sub).'</strong> ') : false; 
        } 
        else // more than 3 levels, something is wrong 
        { 
         for ($i = count($_sub); $i > 1; $i--) 
         { 
          $removed = array_shift($arr); 
         } 
         $debug ? print("<br>\n" . '[*] Three level TLD: <strong>' . join('.', $_sub) . '</strong> ') : false; 
        } 
       } 
       elseif (count($arr) === 2) 
       { 
        $arr0 = array_shift($arr); 

        if (strpos(join('.', $arr), '.') === false 
         && in_array($arr[0], array('localhost','test','invalid')) === false) // not a reserved domain 
        { 
         $debug ? print("<br>\n" .'Seems invalid domain: <strong>'.join('.', $arr).'</strong> re-adding: <strong>'.$arr0.'</strong> ') : false; 
         // seems invalid domain, restore it 
         array_unshift($arr, $arr0); 
        } 
       } 

       $debug ? print("<br>\n".'<strong style="color:gray">&laquo;</strong> Done parsing: <span style="color:red">' . $original . '</span> as <span style="color:blue">'. join('.', $arr) ."</span><br>\n") : false; 

       return join('.', $arr); 
      } 

      $urls = array(
       'www.example.com' => 'example.com', 
       'example.com' => 'example.com', 
       'example.com.br' => 'example.com.br', 
       'www.example.com.br' => 'example.com.br', 
       'www.example.gov.br' => 'example.gov.br', 
       'localhost' => 'localhost', 
       'www.localhost' => 'localhost', 
       'subdomain.localhost' => 'localhost', 
       'www.subdomain.example.com' => 'example.com', 
       'subdomain.example.com' => 'example.com', 
       'subdomain.example.com.br' => 'example.com.br', 
       'www.subdomain.example.com.br' => 'example.com.br', 
       'www.subdomain.example.biz.br' => 'example.biz.br', 
       'subdomain.example.biz.br' => 'example.biz.br', 
       'subdomain.example.net' => 'example.net', 
       'www.subdomain.example.net' => 'example.net', 
       'www.subdomain.example.co.kr' => 'example.co.kr', 
       'subdomain.example.co.kr' => 'example.co.kr', 
       'example.co.kr' => 'example.co.kr', 
       'example.jobs' => 'example.jobs', 
       'www.example.jobs' => 'example.jobs', 
       'subdomain.example.jobs' => 'example.jobs', 
       'insane.subdomain.example.jobs' => 'example.jobs', 
       'insane.subdomain.example.com.br' => 'example.com.br', 
       'www.doubleinsane.subdomain.example.com.br' => 'example.com.br', 
       'www.subdomain.example.jobs' => 'example.jobs', 
       'test' => 'test', 
       'www.test' => 'test', 
       'subdomain.test' => 'test', 
       'www.detran.sp.gov.br' => 'sp.gov.br', 
       'www.mp.sp.gov.br' => 'sp.gov.br', 
       'ny.library.museum' => 'library.museum', 
       'www.ny.library.museum' => 'library.museum', 
       'ny.ny.library.museum' => 'library.museum', 
       'www.library.museum' => 'library.museum', 
       'info.abril.com.br' => 'abril.com.br', 
       '127.0.0.1' => '127.0.0.1', 
       '::1' => '::1', 
      ); 

      $failed = 0; 
      $total = count($urls); 

      foreach ($urls as $from => $expected) 
      { 
       $from = get_domain($from, true); 
       if ($from !== $expected) 
       { 
        $failed++; 
        print("<div style='color:fuchsia;'>expected {$from} to be {$expected}</div>"); 
       } 
      } 

      if ($failed) 
      { 
       print("{$failed} tests failed out of {$total}"); 
      } 
      else 
      { 
       print("Success"); 
      } 

但是我發現,它並沒有在這些情況下工作:

blog.ebaum.tv 
api.outside.in 
chip.cuccio.us 
brushes.net.tc 
beta.wua.la 
core.windows.net 
dd.cron.ru 
compute-1.amazonaws.com 
docs.rinet.ru 
dupont.free.fr 
edusim.greenbush.us 
dtek.chalmers.se 
fifthgear.five.tv 
friizu.pri.ee 
fortune.cnn.com 
grondziowski.neostrada.pl 
iden.tify.us 
fb.joyent.us 
blog.tr.im 
jspec.jaxa.jp 
mashable.blogs.mu 
lists.burri.to 
com.edgesuite.net 
my.noovo.us 
blog.bit.ly 
moon.dominos.jp 

所以,對於上述所有子域,函數,而不是返回域的子域。 有沒有人有想法如何解決這個功能?

+0

該函數始終返回國家/地區特定頂級域下的第三級域。它假定它們都是'organization.type.country'形式,例如'oxford.ac.uk'和'example.co.cr'。 – Barmar 2014-12-27 17:33:37

+0

@Barmar你有想法如何解決它?另外「compute-1.amazonaws.com」是一些錯誤。此外,「dupont.free.fr」應該是「free.fr」等。 – miki22 2014-12-27 17:57:50

+0

不知道每個國家的規則和所有例外情況,我不認爲有任何好的解決方案。 – Barmar 2014-12-27 17:59:26

回答

1

嘗試:

function getDomain ($address) { 

# Establishes Hostname 
$uri[Hostname] = substr($address,0, (strpos($address,'.'))); 

# Establishes Domainname 
$uri[Domainname] = substr($address, (strlen($uri[Hostname]) + 1)); 

if (preg_match("/\//", $uri[Domainname])) { 
$uri[Domainname] = substr($uri[Domainname], 0, strpos($uri[Domainname],'/')); 
} 

# Establishes TLD 
if (preg_match("/\./", $uri[Domainname])) { 
$uri[TLD] = substr($uri[Domainname], (strpos($uri[Domainname],'.') + 1)); 
$uri[Domainname] = substr($uri[Domainname],0,-(strlen($uri[TLD]) + 1)); 
} 

if (preg_match("/\//", $uri[TLD])) { 
$uri[TLD] = substr($uri[TLD], 0, strpos($uri[TLD],'/')); 
} 

# Re-labels parts if there are only 2 (instead of 3) 
if (count($uri) == 2) { 
$uri[TLD] = $uri[Domainname]; 
$uri[Domainname] = $uri[Hostname]; 
unset ($uri[Hostname]); 
} 

# Added to handle domains of type .co.rs, .co.uk, .co.jp etc. 
if ($uri[Domainname] == 'co') { 
$uri[TLD] = $uri[Domainname].'.'.$uri[TLD]; 
$uri[Domainname] = $uri[Hostname]; 
unset ($uri[Hostname]); 
} 

return $uri; 
} 

該函數將採取任何標準的web地址(即,不包括一個多個子域。),並返回包含的主機名(任選地),域名和TLD的陣列。

+0

如果您還需要處理包含多個子域的網址,您可以將包含第二個和第三個「if」語句的塊轉變爲循環,以便從網址中提取每個子域。 – Rounin 2014-12-27 19:18:58

+0

不起作用。 對於域「slajer.co.rs」,它返回「Array([Hostname] => slajer [Domainname] => co [TLD] => rs)」。 但是.co.rs是TLD – miki22 2014-12-28 09:19:56

+0

是的。我在最後添加了一個塊來處理TLD,比如.co.rs,.co.uk,.co.jp等。 – Rounin 2014-12-28 10:30:12

0

您可以輕鬆地通過使用簡單的服務器功能,像下面找出域名...

 echo $_SERVER['SERVER_NAME']; 

OR

起初,你可以創建一個函數像下面..

<?php 

    function getDomain($url){ 
    if(filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_HOST_REQUIRED) === FALSE){ 
     return false; 
    } 

    /*** to get the url parts ***/ 
    $parts = parse_url($url); 

    /*** return the host domain ***/ 
    return $parts['scheme'].'://'.$parts['host']; 

    } 
?> 

然後調用此函數,如下所示:...

<?php 

    $url = 'http://phpro.org/classes/Phproogle-Docs.html'; 
    echo getDomain($url); 
?> 
+0

這絕對是一個有用的全局變量。但是......它不會從URI中提取域。 – Rounin 2014-12-28 10:48:57

+0

現在希望它會返回確切的域名....如果不行,只需發送您期望的域名格式作爲例子... – 2014-12-28 11:02:42