我们可以使用 PHP 来指定特定的 DNS 服务器(如 1.1.1.1、OpenDNS 或 Google DNS)来查询域名的 DNS 解析地址。这里有几种方法可以实现:
使用
dns_get_record()
函数并指定 DNS 服务器:function getDnsRecords($domain, $dnsServer) { $oldResolver = dns_get_record('example.com', DNS_NS); putenv("RES_OPTIONS=nameserver $dnsServer"); $result = dns_get_record($domain, DNS_A); putenv("RES_OPTIONS=nameserver " . $oldResolver[0]['target']); return $result; } $domain = 'example.com'; // 使用 Cloudflare DNS (1.1.1.1) $cloudflareRecords = getDnsRecords($domain, '1.1.1.1'); print_r($cloudflareRecords); // 使用 OpenDNS (208.67.222.222) $openDnsRecords = getDnsRecords($domain, '208.67.222.222'); print_r($openDnsRecords); // 使用 Google DNS (8.8.8.8) $googleDnsRecords = getDnsRecords($domain, '8.8.8.8'); print_r($googleDnsRecords);
使用
fsockopen()
函数直接向 DNS 服务器发送查询:function dnsQuery($domain, $dnsServer, $port = 53, $timeout = 3) { $sock = fsockopen("udp://$dnsServer", $port, $errno, $errstr, $timeout); if (!$sock) return false; $data = "\xAA\xAA\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00"; $data .= chr(strlen($domain)) . $domain . "\x00\x00\x01\x00\x01"; fwrite($sock, $data); $response = fread($sock, 1000); fclose($sock); if (strlen($response) < 12) return false; $answer = substr($response, strlen($data)); $offset = 0; $answerCount = ord($answer[$offset]) * 256 + ord($answer[$offset + 1]); $result = []; for ($i = 0; $i < $answerCount; $i++) { $offset += 12; $ipLength = ord($answer[$offset]) * 256 + ord($answer[$offset + 1]); $offset += 2; $ip = implode('.', array_map('ord', str_split(substr($answer, $offset, $ipLength)))); $result[] = $ip; $offset += $ipLength; } return $result; } $domain = 'example.com'; // 使用 Cloudflare DNS $cloudflareResults = dnsQuery($domain, '1.1.1.1'); print_r($cloudflareResults); // 使用 OpenDNS $openDnsResults = dnsQuery($domain, '208.67.222.222'); print_r($openDnsResults); // 使用 Google DNS $googleDnsResults = dnsQuery($domain, '8.8.8.8'); print_r($googleDnsResults);
这两种方法都允许您使用指定的 DNS 服务器来查询域名的 DNS 解析地址。第一种方法更简单,但可能受到系统 DNS 设置的影响。第二种方法更直接,但需要更多的低级编程。
确实有一些好用的第三方 DNS 查询接口。这些接口通常以 HTTP API 的形式提供,使用起来更简单,也不需要直接处理底层的 DNS 协议。以下是几个流行的选择:
Google DNS-over-HTTPS API:
function googleDnsQuery($domain) { $url = "https://dns.google/resolve?name=$domain&type=A"; $response = file_get_contents($url); return json_decode($response, true); } $result = googleDnsQuery('example.com'); print_r($result);
Cloudflare DNS-over-HTTPS API:
function cloudflareDnsQuery($domain) { $url = "https://cloudflare-dns.com/dns-query?name=$domain&type=A"; $options = [ 'http' => [ 'method' => 'GET', 'header' => 'Accept: application/dns-json' ] ]; $context = stream_context_create($options); $response = file_get_contents($url, false, $context); return json_decode($response, true); } $result = cloudflareDnsQuery('example.com'); print_r($result);
DNS.SB API:
function dnsSbQuery($domain) { $url = "https://dns.sb/api/dns-query?name=$domain&type=A"; $response = file_get_contents($url); return json_decode($response, true); } $result = dnsSbQuery('example.com'); print_r($result);
这些 API 都是免费使用的,但可能有一些使用限制。它们返回的结果是 JSON 格式,包含了详细的 DNS 信息,您可以根据需要解析这些信息。
使用这些 API 的优点是:
- 简单易用,不需要处理复杂的 DNS 协议
- 通过 HTTPS 进行查询,更安全
- 可以绕过本地 DNS 缓存,获得最新的 DNS 信息
缺点可能包括:
- 依赖于第三方服务的可用性
- 可能有使用次数的限制
- 查询速度可能比直接 DNS 查询稍慢
如果您需要在生产环境中大量使用 DNS 查询,可能需要考虑使用付费的 DNS API 服务,它们通常提供更高的查询限制和更好的支持。