如何使用PHP剥离子域以获得有效的根域?

如何使用PHP剥离子域以获得有效的根域?,php,curl,dns,subdomain,Php,Curl,Dns,Subdomain,好的,这里是我正在寻找的:从一个链接列表中,我正在剥离除域之外的所有内容。结果是域和代表子域的域名的混合列表 stackoverflow.com security.stackexchange.com whoknows.test.co.uk you.get.it.by.now.dont.you.com 我要做的是将所有列表项精简到其有效(=仅现有)根域,如下所示: stackoverflow.com security.stackexchange.com test.co.uk -fail- 目前

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

stackoverflow.com
security.stackexchange.com
whoknows.test.co.uk
you.get.it.by.now.dont.you.com
我要做的是将所有列表项精简到其有效(=仅现有)根域,如下所示:

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 
有没有其他方法可以做到这一点?我想停止对我的100.000+列表中的每个域进行2到X(=几乎无限)的卷曲查找,从而加热我的Web服务器的CPU。而且,所有这些查找都需要花费大量时间。也许——我希望如此——有一个更快的解决办法


陷阱?它必须与PHP一起工作。

有许多快捷方式可以满足您的需要

例如,您已经知道
.co.uk
.com
是TLD,因此检查它们显然可以跳过

问题在于所有其他疯狂的TLD

我建议你看一下你的资料来源

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

所以

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

最后,我选择了一个不同的“gethostbyname”函数来解决我的问题,该函数将IP6考虑在内

函数my\u gethostbyname($host,$try\u a=FALSE)
{
$dns=gethostbynamel6($host,$try_a);
如果($dns==FALSE)
{ 
返回FALSE;
}
其他的
{ 
返回$dns[0];
}
}
函数gethostbynamel6($host,$try\u a=FALSE)
{
$dns=array();
$dns6=@dns_get_记录($host,dns_AAAA);
如果($dns6!==FALSE)
{
$dns=数组合并($dns,$dns6);
}
如果($try_a==TRUE)
{
$dns4=@dns\u get\u记录($host,dns\u A);
如果($dns4!==FALSE)
{
$dns=数组合并($dns,$dns4);
}
}
其他的
{
$dns=$dns6;
}
$ip6=数组();
$ip4=数组();
foreach($dns作为$record)
{
如果($record[“type”]=“A”)
{
$ip4[]=$record[“ip”];
}
如果($record[“type”]=“AAAA”)
{
$ip6[]=$record[“ipv6”];
}
}
如果(计($ip6)<1)
{
如果($try_a==TRUE)
{
如果(计($ip4)<1)
{
返回FALSE;
}
其他的
{
返回$ip4;
}
}
其他的
{
返回FALSE;
}
}
其他的
{
返回$ip6;
}
}
一旦第一个域部分实际解析为IP,(a)该域存在,(b)是根域

这为我节省了大量时间,其中的诀窍是,你的速度只与你的DNS解析和一些微服务器一样慢。我以前使用的curl选项每次调用大约需要3秒(有时达到我设置为20秒的完整超时范围),这取决于目标服务器的响应时间(如果有的话)

我现在选择的路径很容易理解:我最终得到了一个解析域列表,如果需要,我可以使用curl“按需”或使用一个或多个CRON作业“按间隔”检查这些域

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

我从中学到了什么…

  • 在检查域时,首先尝试解析它们,这样就可以避免curl带来的超时负担
  • Curl对于很多任务来说都很好,但它并不是尝试用它做所有事情的最聪明的方法
  • 当你认为你不能解决一个问题超过你已经尝试做的,把问题分成两个或更多的部分,然后再次检查。机会很大,你会发现一个全新的世界的选择,以提高你所拥有的
  • 我希望这能减轻一个人几个星期来摆弄同样问题的负担

    类域utils{
    函数_u构造(){
    //只有这些超级域
    $this->superDomains=array(
    “.com”,
    “.gov”,
    “.org”,
    “.co.uk”,
    “.info”,
    “.co”,
    “.net”,
    “.我”,
    "电视",,
    “莫比先生”
    );  
    }
    //获取超级域
    公共函数getMainDomain($domain=null){
    $domainChunks=explode('.',str_-ireplace($this->superDomains,,$domain));
    if(sizeof($domainChunks)==0){
    返回false;
    }
    foreach($key=>$domainChunk的域块){
    如果($key
    @egis:这无助于找到根域,它只解析url并返回(除其他外)主机。我需要知道并验证该主机的根域!请定义一个“有效根域”-这不是DNS中可识别的术语。我将“有效”定义为“仅存在”。但是如果你完全检查了这个问题,你会注意到这不是唯一的DNS问题。哦,当我这么做的时候:DNS不“识别术语”,但我打赌你知道我会这么说。。。你不是吗干杯。这就是为什么我用“.”(点)来分解它,然后从头到尾工作
    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;
        }
    }
    
    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;
      } 
    }