代码之家  ›  专栏  ›  技术社区  ›  Gavin M. Roy

转到php parse_url()没有的地方-只分析域

  •  12
  • Gavin M. Roy  · 技术社区  · 17 年前

    php的parse_url()有一个包含完整主机的主机字段。我正在寻找最可靠(也是最便宜)的方法来只返回域和TLD。

    举例来说:

    我只想找 Google网站 谷歌公司 .我考虑了一个有效的TLD/后缀表,只允许这些和一个单词。你能用其他方法吗?有人知道这种东西的预罐装有效regex吗?

    8 回复  |  直到 10 年前
        1
  •  17
  •   lpfavreau Arthur Debert    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;
    }
    

    将使用Classic提取域名 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 ,因此请确保它是格式良好的URL。

    /附录:

    阿尼塔克是对的。上述解决方案将在 但不一定是所有的病例,需要对其进行维护,以确保它们不是新的具有6个以上特征的TLD,等等。提取域的唯一可靠方法是使用维护的列表,例如 http://publicsuffix.org/ . 一开始更痛苦,但从长远来看更容易,更健壮。您需要确保了解每个方法的优缺点,以及它如何适合您的项目。

        2
  •  6
  •   Community Mohan Dere    9 年前

    目前唯一“正确”的方法是使用一个列表,如 http://publicsuffix.org/

    顺便说一句,这个问题也相当类似于:

    IETF正在研究DNS方法,以声明DNS树中的特定节点是否用于“公开”注册,但它们正处于开发的早期阶段。所有流行的非IE浏览器都使用publicSuffix.org列表。

        3
  •  3
  •   Martin B.    12 年前

    python的tldextact模块还有一个非常好的端口 http://w-shadow.com/blog/2012/08/28/tldextract -这超出了解析URL的范围,允许您实际获取域/TLD,而不需要子域。

    从模块网站:

    $components = tldextract('http://www.bbc.co.uk');
    echo $components->subdomain; // www
    echo $components->domain;    // bbc
    echo $components->tld;       // co.uk
    
        4
  •  1
  •   Gavin M. Roy    17 年前

    从一个相关的岗位上挖出来,为了保持一张桌子: http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/src/effective_tld_names.dat?raw=1

    但我不想那样做。

        5
  •  0
  •   mark    17 年前

    当然,这取决于您的具体用例,但一般来说,我不会使用表查找来查找TLD。新的TLD出现了,你通常不想在任何地方维护它们。问一下我的firstname@lastname.name因为近视被拒绝的频率。

    如果我知道你为什么不想要WWW,我想我能帮得上忙吗?你需要它来收发邮件吗?在这种情况下,您可以查询MX记录以验证它(最终)是否接受邮件。

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

        6
  •  0
  •   Eineki    17 年前

    只是一个证明,假设允许的TLD被存储到哈希中。 代码可以缩短很多。

    <?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
        }
    ?>
    
        7
  •  0
  •   Oleksandr Fediashov    10 年前

    您需要使用的包 Public Suffix List 只有这样,才能正确地提取具有两个、三级TLD(co.uk、a.bg、b.bg等)和多级子域的域。regex、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'
    
        8
  •  -2
  •   Kruppe    17 年前

    有一个非常简单的解决方案:

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

    这肯定行吗?

    推荐文章