此方法没有错误处理,它只是输出“false”,并且无法检查 NXDOMAIN、SERVFAIL、TIMEOUT 或任何其他错误……
(PHP 5, PHP 7, PHP 8)
dns_get_record — 获取与主机名关联的DNS资源记录
$hostname
,$type
= DNS_ANY
,&$authoritative_name_servers
= null
,&$additional_records
= null
,$raw
= false
获取与给定hostname
关联的DNS资源记录。
hostname
hostname
应为有效的DNS主机名,例如"www.example.com
"。可以使用in-addr.arpa
表示法生成反向查找,但是对于大多数反向查找,gethostbyaddr() 更为合适。
注意:
根据DNS标准,电子邮件地址采用
user.host
格式(例如:hostmaster.example.com
而不是[email protected]
),请务必检查此值并在使用诸如mail()之类的函数之前进行必要的修改。
type
默认情况下,dns_get_record() 将搜索与hostname
关联的任何资源记录。若要限制查询,请使用DNS_*
常量之一。
authoritative_name_servers
通过引用传递,如果给出,将填充权威名称服务器的资源记录。
additional_records
通过引用传递,如果给出,将填充任何附加记录。
raw
type
将被解释为原始DNS类型ID(不能使用DNS_*
常量)。返回值将包含一个data
键,需要手动解析。
此函数返回关联数组的数组,或者在失败时返回false
。每个关联数组都至少包含以下键
属性 | 含义 |
---|---|
host | DNS命名空间中其余关联数据所引用的记录。 |
class |
dns_get_record() 只返回Internet类记录,因此此参数将始终返回IN 。 |
type | 包含记录类型的字符串。根据type的值,结果数组中还将包含其他属性。见下表。 |
ttl |
"生存时间" 此记录的剩余时间。这不等于记录的原始ttl,而是等于原始ttl减去自查询权威名称服务器以来经过的时间。 |
类型 | 额外列 |
---|---|
A |
ip :点分十进制表示法的IPv4地址。 |
MX |
pri :邮件交换器的优先级。数字越小,优先级越高。target :邮件交换器的FQDN。另见dns_get_mx()。 |
CNAME |
target :DNS命名空间中记录所指向的位置的FQDN。 |
NS |
target :对此主机名具有权威性的名称服务器的FQDN。 |
PTR |
target :此记录指向的DNS命名空间中的位置。 |
TXT |
txt :与此记录关联的任意字符串数据。 |
HINFO |
cpu :指定此记录引用的机器的CPU的IANA编号。os :指定此记录引用的机器的操作系统的IANA编号。有关这些值的含义,请参阅IANA的» Operating System Names 。 |
CAA |
flags :一个字节的位域;目前仅定义位0,表示“关键”;其他位保留,应忽略。tag :CAA标签名称(字母数字ASCII字符串)。value :CAA标签值(二进制字符串,可以使用子格式)。更多信息请参见:» RFC 6844 |
SOA |
mname :资源记录来源的机器的FQDN。rname :此域的管理联系人的电子邮件地址。serial :此请求域的修订版的序列号。refresh :辅助名称服务器在更新此域的远程副本时应使用的刷新间隔(秒)。retry :刷新失败后等待再次尝试的时间长度(秒)。expire :辅助DNS服务器在成功刷新之前应保留区域数据的远程副本的最长时间(秒),之后应将其丢弃。minimum-ttl :客户端在请求服务器的新解析之前可以继续使用DNS解析的最短时间(秒)。可以被各个资源记录覆盖。 |
AAAA |
ipv6 :IPv6地址 |
A6 |
masklen :从chain 指定的target继承的长度(以位为单位)。ipv6 :此特定记录的地址,与chain 合并。chain :与ipv6 数据合并的父记录。 |
SRV |
pri :(优先级)应首先使用最低优先级。weight :排名,用于随机选择通常具有优先级的targets 中的哪一个。target 和port :可以找到请求服务的hostname和端口。更多信息请参见:» RFC 2782 |
NAPTR |
order 和pref :与上面的pri 和weight 等效。flags 、services 、regex 和replacement :由» RFC 2915定义的参数。 |
版本 | 描述 |
---|---|
7.0.16, 7.1.2 | 添加了对CAA记录类型的支持。 |
示例 #1 使用dns_get_record()
<?php
$result = dns_get_record("php.net");
print_r($result);
?>
以上示例将输出类似于以下内容
Array ( [0] => Array ( [host] => php.net [type] => MX [pri] => 5 [target] => pair2.php.net [class] => IN [ttl] => 6765 ) [1] => Array ( [host] => php.net [type] => A [ip] => 64.246.30.37 [class] => IN [ttl] => 8125 ) )
示例 #2 使用dns_get_record() 和 DNS_ANY
由于在解析MX记录后通常需要邮件服务器的IP地址,dns_get_record()还在additional_records
中返回一个数组,其中包含关联记录。authoritative_name_servers
也作为返回值返回,其中包含权威名称服务器列表。
<?php
/* 请求 php.net 的“任意”记录,
并创建包含域名服务器列表的 $authns 数组和
任何与其相关的附加记录的 $addtl 数组
*/
$result = dns_get_record("php.net", DNS_ANY, $authns, $addtl);
echo "Result = ";
print_r($result);
echo "Auth NS = ";
print_r($authns);
echo "Additional = ";
print_r($addtl);
?>
以上示例将输出类似于以下内容
Result = Array ( [0] => Array ( [host] => php.net [type] => MX [pri] => 5 [target] => pair2.php.net [class] => IN [ttl] => 6765 ) [1] => Array ( [host] => php.net [type] => A [ip] => 64.246.30.37 [class] => IN [ttl] => 8125 ) ) Auth NS = Array ( [0] => Array ( [host] => php.net [type] => NS [target] => remote1.easydns.com [class] => IN [ttl] => 10722 ) [1] => Array ( [host] => php.net [type] => NS [target] => remote2.easydns.com [class] => IN [ttl] => 10722 ) [2] => Array ( [host] => php.net [type] => NS [target] => ns1.easydns.com [class] => IN [ttl] => 10722 ) [3] => Array ( [host] => php.net [type] => NS [target] => ns2.easydns.com [class] => IN [ttl] => 10722 ) ) Additional = Array ( [0] => Array ( [host] => pair2.php.net [type] => A [ip] => 216.92.131.5 [class] => IN [ttl] => 6766 ) [1] => Array ( [host] => remote1.easydns.com [type] => A [ip] => 64.39.29.212 [class] => IN [ttl] => 100384 ) [2] => Array ( [host] => remote2.easydns.com [type] => A [ip] => 212.100.224.80 [class] => IN [ttl] => 81241 ) [3] => Array ( [host] => ns1.easydns.com [type] => A [ip] => 216.220.40.243 [class] => IN [ttl] => 81241 ) [4] => Array ( [host] => ns2.easydns.com [type] => A [ip] => 216.220.40.244 [class] => IN [ttl] => 81241 ) )
一次获取多种类型,如下所示
<?php
$dnsr = dns_get_record('php.net', DNS_A + DNS_NS);
print_r($dnsr);
?>
在 DNS_ANY 可行的某些域名上,使用 DNS_ALL 会失败。我注意到该函数卡在了 DNS_PTR 记录上,这导致它返回 FALSE 并出现此错误
PHP Warning: dns_get_record(): res_nsend() failed in ....
这将获取所有记录,除了 DNS_PTR
<?php
$dnsr = dns_get_record('php.net', DNS_ALL - DNS_PTR);
print_r($dnsr);
?>
您可能与我遇到同样的问题,测试不存在的域名将搜索相对于您正在执行的域的子域名,例如
// 使用有效的域名进行测试
var_dump( dns_get_record('google.com', DNS_A) );
/* 可行,返回
数组
(
[host] => google.com
[class] => IN
[ttl] => 299
[type] => A
[ip] => 172.217.12.142
)
*/
// 在我们的网站上测试无效域名 (example.com)
var_dump( dns_get_record('invalidtestingname.com', DNS_A) );
/* 不起作用,假装它是一个子域名
数组
(
[host] => invalidtestingname.com.example.com
[class] => IN
[ttl] => 299
[type] => A
[ip] => xxx.xxx.xxx.xxx
)
*/
如果有人遇到此问题,请在域名末尾添加一个“点”,例如,不要使用
dns_get_record('invalidtestingname.com', DNS_A);
请使用
dns_get_record('invalidtestingname.com.', DNS_A);
虽然这非常适用于一般的 DNS 查询,但如果您想对指定的 DNS 服务器进行直接 DNS 查询(而不是使用操作系统解析),请尝试使用 PHPDNS:http://www.purplepixie.org/phpdns/
您可以对名称服务器进行直接(TCP 或 UDP)低级别查询,并随意递归。这对于测试特定服务器以及逐步进行递归解析非常有用。
请注意,防火墙和反恶意软件会检测(并根据公司策略甚至阻止)DNS_ANY 请求。
在这种情况下,此函数的使用会失败。
这是因为 DNS_ANY 请求可用于创建“放大 (D)DOS 攻击”:您发送 1 个 DNS_ANY 请求,并获得大量信息作为回应,因此即使是小的请求也会导致巨大的网络负载。
我建议使用更明确的名称请求,而不是使用 DNS_ANY。
当我在 Windows 操作系统上使用 DNS_ALL 作为第二个参数调用 dns_get_record() 时,PHP 会发出一条警告消息“Warning: dns_get_record(): Type '251721779' not supported in blah.php on line blah”,而 DNS_ANY 始终正常。
遗憾的是,此方法不允许使用任意名称服务器。
如果您需要使用特定 DNS 服务器发出请求,则需要使用 Pear/Net_DNS2 或 libdns(https://github.com/DaveRandom/LibDNS)。
如果您想要更短更轻量的东西,您也可以使用这个 150 行的函数:https://gist.github.com/bohwaz/ddc61c4f7e031c3221a89981e70b830c