我有两个正在使用的文本文件。第一个文本文件名为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在这个链接上发布了一个类似的问题。返回域php的名称服务器数组,但我们使用的逻辑完全不同,这就是为什么我再次提问。
我可以看到这个脚本可能存在的两个问题:
-
fopen($regfile,'a')
将打开一个文件进行写入,将内部指针放在文件的端。尝试使用fopen($regfile,'r+')
,它会将指针放在文件的*开头。 -
当主机名中出现"空白"时,您会中断
while
循环,这将使循环停止。代码中没有任何内容允许脚本再次开始循环。
考虑使用continue
语句而不是break
,这将在标记点停止循环,但允许它从列表中的下一个项目再次继续循环。
首先,我们用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);
}
?>