用于从修剪区域文件(txt文件)收集名称服务器数组的PHP脚本

时间:2016-05-08 20:52:37

标签: php arrays dns

我有两个正在使用的文本文件。第一个文本文件名为get-domain.txt,它包含以下格式的域列表:

000,
1,
10,
101domain,
11,

第二个文件是一个名为final-file.txt的修剪区域文件,它包含以下格式的域及其名称服务器:

000 NS ns2.mailart.com. 
 NS ns3.mailart.com. 


1 NS NS1.MAILART.COM. 
 NS NS2.MAILART.COM. 


10 NS pns22.cloudns.net.
 NS ns24.cloudns.net. 


101domain NS ns1.101domain.com. 
 NS ns2.101domain.com. 


11 NS f1g1ns1.dnspod.net.
 NS f1g1ns2.dnspod.net. 

我编写了一个循环遍历两个文件的脚本,当第一个文件中的域与第二个文件中的域匹配时,我应该收集该域的名称服务器并将它们写入另一个名为file-to-compare的文件。 txt采用以下格式:

000.mw, ns2.mailart.com.,
000.mw, ns3.mailart.com.,

但是,我面临的问题是我编写的php脚本只能收集第一个名称服务器。如果域名不止一个,它无法获得域名的其余名称服务器。以下是我脚本的示例输出:

000.mw, ns2.mailart.com., 
000.mw, ns2.mailart.com.,  

以下是我的代码:

//open a file to read domains from
$domains = fopen("get-domain-final.txt", "r") or die("Cant open the get-      domain-final file"); //open the file containing all domains
while (!feof($domains))

{
    $dom_arr = array(); $d = 0; //define n declare domain array n its index
    $m=0; //checks if an array contains a value
    $b=0; 
    $array = explode(",", fgets($domains)); //make an array using comma inorder to get the domain
    $domain=$array[0];

    //***************** opening final trimed zone file**********************//
    $exp = "final-file.txt"; 
    $fp = fopen("$exp",'r') or die("Cant open the final trimed zone file"); 

    //***************** opening file to write our results to**********************//
    $regfile = "file-to-compare.txt";  //assign the file to a variable
    $fh = fopen($regfile,'a') or die("Cant open the reg file"); 

    while(!feof($fp)){
         $blank=fgets($fp); //get the line from the file  //it wrkd as well--> $blank=trim(fgets($fp));if(empty($blank))
         $fields = explode(" ",$blank);  //explode the line by space
         //echo $fields[2]."<br/>"; // display de exploded values of array i.e verizon.mw 
         //check for the NS of the same domain as above
         if( ("$domain") == strtolower((trim($fields[0]))) ){ //get NSs of the domain
            //if ("$domain" == "$fields[0]")$b=1;} //ctrl the lines of that domain to read its NS
            //if ($b>=1){break;}
            //echo $fields[2]."<br/>"; //for testing
            $dom_arr[$d++] = $fields[2]; //assign ns to array index
            $m=1;//helps to control of which next lines of that domain to read and get the NSs
            //continue;
        }


        if( ($m==1) && preg_match("/^$/",trim($blank)) ){
            //for($i=0;$i<$d;$i++){
            //  echo $dom_arr[$i]."<br/><br/>";
            break;//} //controls where to stop reading the NS of the domain
          }

        if( ( $m==1)&& (preg_match("/^$/",trim($fields[0])) ) ){ //get NSs of the domain same as above
            //echo $fields[2]."<br/>"; //for testing
            $dom_arr[$d++] = $fields[2]; //assign ns to array index
            //continue;
            }   

        //*************display the name servers and write them to a file**************//
        echo "<br/>";
        echo "NSs of domain $domain:<br/>";
        for($i=0;$i<$d;$i++){ //print out the found NSs
            echo $dom_arr[$i]."<br/>";
            $fields = "$domain.mw, $dom_arr[$i], \n";
             fwrite($fh,$fields);  //add the domains and expiry the to file
             break; //break each for loop
        }
    }
    fclose($fp); //close the final trimed zone file


}//end of while loop for file containing all domains
fclose($domains); //close the file containing all domains

Some One在这个链接Returning array of nameservers for domain php上发布了一个类似的问题,但我们使用的逻辑完全不同,这就是我再次提出要求的原因。

2 个答案:

答案 0 :(得分:0)

我可以看到这个脚本有两个可能的问题:

  1. fopen($regfile,'a')将打开一个文件进行写入,将内部指针放在文件的 end 。尝试使用fopen($regfile,'r+')将指针放在文件的*开头。

  2. 在遇到&#34;空白&#34;时,您会中断while循环在主机名中,这将停止循环死亡。代码中没有任何内容允许脚本再次开始循环。

  3. 考虑使用continue语句而不是break语句,它将在标记点停止循环,但允许它从列表中的下一项继续循环。

答案 1 :(得分:0)

首先,我们将所有域都放入file()的数组中。然后,我们使用array_map()遍历每个域,并使用rtrim()删除域末尾的逗号。所以我们得到了一个$domains数组:

Array
(
    [0] => 000
    [1] => 1
    [2] => 10
    [3] => 101domain
    [4] => 11
)

之后我们将名称服务器文件作为字符串file_get_contents()获取。然后,我们将此字符串与preg_split()分开2行或更多行,这样我们就可以在一个数组元素中获得每个域的所有名称服务器。

但是每个域的名称服务器都不是非常方便的格式。所以我们遍历数组,然后用substr()得到一个域,在那里我们从元素的开头得到子串,直到第一次出现NS我们得到strpos()的位置,第二个我们得到preg_match_all()的所有名称服务器,我们在NS之后得到所有名称。然后我们将$nameservers数组放在一个方便的格式中:

Array (
    domain => Array(nameserver1, nameserver2, ...),
    //...
)

现在我们只需要按键获取两个数组$domains$nameservers的交集,我们可以使用array_intersect_key()轻松完成。

最后剩下要做的就是绕过交叉路口并以file_put_contents()的格式保存数据。

代码

<?php

    $domains = array_map(function($v){
        return rtrim($v, ",");
    }, file("test.txt", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES));
    $nameserversTmp = preg_split("/(?=\R\s*\R)[\R\s]+/", file_get_contents("test2.txt"));
    $nameservers = [];

    foreach($nameserversTmp as $nameserver){
        $domain = substr($nameserver, 0, strpos($nameserver, " NS"));
        preg_match_all("/NS ([\w.]+)/", $nameserver, $m);

        $nameservers[$domain] = $m[1];
    }

    $intersect = array_intersect_key($nameservers, array_flip($domains));

    foreach($intersect as $domain => $nameserverList){
        file_put_contents("final.txt", $domain . ".mw, " . implode(", " . PHP_EOL . $domain . ".mw, ", $nameserverList) . PHP_EOL, FILE_APPEND);
    }

?>