此方法没有错误处理,它只是输出“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
关联的任何资源记录。要限制查询,请指定可选的 type
参数。可以是以下任何一个:DNS_A
,DNS_CNAME
,DNS_HINFO
,DNS_CAA
,DNS_MX
,DNS_NS
,DNS_PTR
,DNS_SOA
,DNS_TXT
,DNS_AAAA
,DNS_SRV
,DNS_NAPTR
,DNS_A6
,DNS_ALL
或 DNS_ANY
。
注意:
由于不同平台之间的 libresolv 性能差异,
DNS_ANY
并不总是会返回所有记录,较慢的DNS_ALL
会更可靠地收集所有记录。
注意:
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 指定的目标继承的长度(以位为单位)。 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 的“ANY”记录,
并创建 $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_ALL 在某些域中失败,而 DNS_ANY 在这些域中有效。我注意到该函数在 DNS_PTR 记录上卡住,导致它返回 FALSE 并出现以下错误
PHP 警告:dns_get_record():res_nsend() 在 .... 中失败
这将获取除 DNS_PTR 之外的所有记录
<?php
$dnsr = dns_get_record('php.net', DNS_ALL - DNS_PTR);
print_r($dnsr);
?>
虽然这非常适用于一般的 DNS 查询,但如果你想对指定的 DNS 服务器进行直接 DNS 查询(而不是使用操作系统解析),请尝试使用 PHPDNS:http://www.purplepixie.org/phpdns/
你可以对名称服务器进行直接(TCP 或 UDP)低级查询,并随意递归。这对于测试特定服务器以及遍历递归解析非常有用。
你可能和我遇到了同样的问题,即测试一个不存在的域名会搜索相对于你执行的域名的子域名,例如
// 使用有效域名进行测试
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_ANY 请求。
在这种情况下,此函数的使用将失败。
这是因为 DNS_ANY 请求可以被用于创建“放大 (D)DOS 攻击”:你发送一个 DNS_ANY 请求,并获得大量信息,因此即使是小的请求也会导致巨大的网络负载。
我建议使用更明确的名称请求,而不是使用 DNS_ANY。
当我在 Windows 操作系统上使用 DNS_ALL 作为 dns_get_record() 的第二个参数调用时,PHP 会发出一个警告,消息为“警告:dns_get_record():类型 '251721779' 在 blah.php 的第 blah 行不支持”,而 DNS_ANY 始终有效。
遗憾的是,此方法不允许使用任意名称服务器。
如果你需要使用特定 DNS 服务器发出请求,你需要使用 Pear/Net_DNS2 或 libdns(https://github.com/DaveRandom/LibDNS)。
如果你想要更短、更轻的东西,你也可以使用这个 150 行函数:https://gist.github.com/bohwaz/ddc61c4f7e031c3221a89981e70b830c
下面有 7 年前的评论提到 BSD 和 MacOSX,我只是想跟进,以防有些人看到并认为它在 MacOSX 上不起作用。
软件
系统软件概述
系统版本:OS X 10.8.3 (12D78)
内核版本:Darwin 12.3.0
启动卷:Macintosh HD
启动模式:正常
计算机名称:Karl 的 iMac
用户名:Karl Kloppenborg (karl)
安全虚拟内存:已启用
自启动以来的时间:10 天 20:24
--------------
# php -a
php > print_r(dns_get_record('google.com', DNS_MX));
数组
(
[0] => 数组
(
[host] => google.com
[type] => MX
[pri] => 10
[target] => aspmx.l.google.com
[class] => IN
[ttl] => 749
)
[1] => 数组
(
[host] => google.com
[type] => MX
[pri] => 30
[target] => alt2.aspmx.l.google.com
[class] => IN
[ttl] => 749
)
[2] => 数组
(
[host] => google.com
[type] => MX
[pri] => 50
[target] => alt4.aspmx.l.google.com
[class] => IN
[ttl] => 749
)
[3] => 数组
(
[host] => google.com
[type] => MX
[pri] => 40
[target] => alt3.aspmx.l.google.com
[class] => IN
[ttl] => 749
)
[4] => 数组
(
[host] => google.com
[type] => MX
[pri] => 20
[target] => alt1.aspmx.l.google.com
[class] => IN
[ttl] => 749
)
)