如何使用PHP删除子域以获取有效的根域?

时间:2011-12-14 07:01:01

标签: php curl dns subdomain

好的,这就是我要找的东西:从链接列表中,除了域名之外,我正在剥离所有内容。结果是一个混合的域名和域名列表,代表子域名。

stackoverflow.com
security.stackexchange.com
whoknows.test.co.uk
you.get.it.by.now.dont.you.com

我想要做的是将所有列表条目修剪为其VALID(=仅存在)根域,如下所示:

stackoverflow.com
security.stackexchange.com
test.co.uk
-fail-

目前我将每一行分解为数组并从后到前处理我的列表,使用curl检查每个潜在的根域是否存在...一旦curl抛出HTTP代码> = 200并且< 400,我认为找到了根域。当每个潜在的域查找结束并且根本没有找到有效域时,该域被认为是不存在的。

input:  stackoverflow.com
test:   stackoverflow.com  - succeeds and is the root domain
result: stackoverflow.com  - valid root domain

input:  whoknows.test.co.uk
test:   co.uk              - fails
test:   test.co.uk         - succeeds (theoretically) and is the root domain
result: test.co.uk         - valid root domain        

input:  you.get.it.by.now.dont.you.com
test:   you.com                         - fails 
test:   dont.you.com                    - fails 
test:   now.dont.you.com                - fails 
test:   by.now.dont.you.com             - fails 
test:   it.by.now.dont.you.com          - fails 
test:   get.it.by.now.dont.you.com      - fails 
test:   you.get.it.by.now.dont.you.com  - fails 
result: you.get.it.by.now.dont.you.com  - invalid domain 

有没有其他方法可以做到这一点?我想停止为我的网络服务器的CPU加热,我的100.000+列表中的每个域都有2到X(=接近无限制)的卷曲查找。此外,所有这些查找都需要花费大量时间。也许 - 所以我希望 - 有一个更快的解决方案来做到这一点。

捕获?它必须与PHP一起使用。

3 个答案:

答案 0 :(得分:1)

有许多快捷方式可以实现您的需求。

例如,您已经知道.co.uk.com是TLD,因此检查这些内容显然可以跳过。

问题在于所有其他疯狂的顶级域名。

我建议您查看ruby-domain-name

的来源

他们使用RFC和已知数据做了大量工作,尝试以正确的方式处理它。

答案 1 :(得分:0)

因此...

我已经花了很长时间来解决这个问题,寻找潜在的瓶颈,经过几天的来回,我发现它实际上是CURL(等待各个服务器用HTTP代码响应)这使得事情变得比需要的慢。

最后,我选择了不同的“gethostbyname”功能,该功能将IP6考虑在内以解决我的问题

function my_gethostbyname($host, $try_a = FALSE) 
{
    $dns = gethostbynamel6($host, $try_a);
    if ($dns == FALSE) 
    { 
        return FALSE; 
    }
    else 
    { 
        return $dns[0]; 
    }
}
function gethostbynamel6($host, $try_a = FALSE) 
{
    $dns = array();
    $dns6 = @dns_get_record($host, DNS_AAAA);
    if($dns6!== FALSE)
    {
        $dns = array_merge($dns, $dns6);
    }
    if ($try_a == TRUE) 
    {
        $dns4 = @dns_get_record($host, DNS_A);
        if($dns4!== FALSE)
        {
            $dns = array_merge($dns, $dns4);
        }
    }
    else
    {
        $dns = $dns6;
    }
    $ip6 = array();
    $ip4 = array();
    foreach ($dns as $record) 
    {
        if ($record["type"] == "A") 
        {
            $ip4[] = $record["ip"];
        }
        if ($record["type"] == "AAAA") 
        {
            $ip6[] = $record["ipv6"];
        }
    }
    if (count($ip6) < 1) 
    {
        if ($try_a == TRUE) 
        {
            if (count($ip4) < 1) 
            {
                return FALSE;
            }
            else 
            {
                return $ip4;
            }
        }
        else 
        {
            return FALSE;
        }
    }
    else 
    {
        return $ip6;
    }
}

只要第一个域部分实际解析为IP,(a)域存在且(b)是根域。

这使我节省了大部分时间,而这样做的诀窍在于,你的DNS解析速度和微软速度一样慢。我之前使用的curl选项每次调用大约需要3秒钟(有时达到我设置为20秒的完整超时范围),具体取决于目标服务器的响应时间 - 如果有的话。

我现在选择的路径很容易理解:我最终得到了一个解析域列表,并且 - 在需要时 - 我可以“按需”检查那些使用curl的那些,或者“间隔”使用一个或多个CRON作业。< / p>

我知道这是一种解决方法,但是将问题分成两个任务(1 =预检查根域,2 =检查域是否返回预期的HTTP代码)使整个过程比完成整个过程更快使用curl立刻工作。

我从中学到了什么......

  1. 检查域名时,请先尝试解决这些问题,这样就可以免除卷曲带来的超时负担。
  2. Curl非常适合许多任务,但它并不是尝试用它做所有的最明智的方法。
  3. 当您认为自己无法解决问题时,请将问题拆分为两个或多个部分,然后再次检查。很有可能你会发现一个全新的选择世界来增强你的成就。
  4. 我希望这可以让人免于摆弄几周类似的问题。 ;)

答案 2 :(得分:0)

class DomainUtils {
  function __construct(){

    //only these super domains
    $this->superDomains = array(
        '.com',
        '.gov',
        '.org',
        '.co.uk',
        '.info',
        '.co',
        '.net',
        '.me',
        '.tv',
        '.mobi'
    );  
  }

  //get super domain
  public function getMainDomain($domain = null){
    $domainChunks = explode('.', str_ireplace($this->superDomains, '', $domain));
    if(sizeof($domainChunks) == 0){
        return false;
    }
    foreach($domainChunks as $key => $domainChunk){
        if($key < sizeof($domainChunks) - 1){ 
            $domain = str_ireplace($domainChunk . '.', '', $domain); 
        }
    }
    return $domain;
  } 
}