本文目录导读:

在 PHP 中进行 DNS 排查,通常涉及确认域名解析是否正常、解析速度、以及定位是 PHP 配置问题还是服务器系统问题,以下是系统的排查步骤和常用方法:
基础PHP脚本测试
使用 dns_get_record() 函数
这是最直接的排查方式,可以查看 DNS 记录的详细信息。
<?php $domain = 'example.com'; // 获取 A 记录 $records = dns_get_record($domain, DNS_A); echo "A Records:<br>"; print_r($records); // 获取 NS 记录 $ns_records = dns_get_record($domain, DNS_NS); echo "<br>NS Records:<br>"; print_r($ns_records); // 获取 MX 记录 $mx_records = dns_get_record($domain, DNS_MX); echo "<br>MX Records:<br>"; print_r($mx_records); // 检查返回错误信息 var_dump($records); ?>
使用 checkdnsrr() 函数
用于快速检查 DNS 记录是否存在。
<?php
$domain = 'example.com';
// 检查 A 记录
if (checkdnsrr($domain, 'A')) {
echo "DNS A record found";
} else {
echo "DNS A record not found";
}
// 检查 MX 记录
if (checkdnsrr($domain, 'MX')) {
echo "MX record exists";
}
?>
测试 DNS 解析时间(性能排查)
<?php
$domain = 'example.com';
$start_time = microtime(true);
// 进行 DNS 查询
dns_get_record($domain, DNS_A);
$end_time = microtime(true);
$execution_time = ($end_time - $start_time) * 1000;
echo "DNS resolution time: " . number_format($execution_time, 2) . " ms";
// 如果超过100ms,需要检查DNS服务器配置
if ($execution_time > 100) {
echo " - Warning: DNS resolution is slow, check /etc/resolv.conf";
}
?>
排查 PHP 配置问题
检查 PHP 配置
# 在命令行中执行 php -i | grep -i dns php -m | grep -i dns
检查 php.ini 相关配置
<?php
// 检查 DNS 相关配置
echo "PHP DNS settings:<br>";
echo "DNS Retry Timeout: " . ini_get('dns_retry_timeout') . "<br>";
echo "DNS FIFO: " . ini_get('dns_fifo') . "<br>";
// 查看 PHP 版本和扩展
echo "PHP Version: " . phpversion() . "<br>";
// 检查是否有 gethostbyname 相关的缓存设置
echo "Hosts resolution cache: " . ini_get('hosts_resolution') . "<br>";
?>
使用 cURL 进行综合测试
<?php
$ch = curl_init();
// 设置选项
curl_setopt($ch, CURLOPT_URL, "https://example.com");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_DNS_CACHE_TIMEOUT, 120); // DNS缓存时间
// 获取详细的连接信息
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
$response = curl_exec($ch);
if (curl_errno($ch)) {
echo 'cURL error: ' . curl_error($ch);
} else {
// 获取连接信息
$info = curl_getinfo($ch);
echo "DNS resolution time: " . $info['namelookup_time'] . " seconds<br>";
echo "Connect time: " . $info['connect_time'] . " seconds<br>";
echo "Total time: " . $info['total_time'] . " seconds<br>";
// 查看DNS解析的具体信息
$dns_result = gethostbyname('example.com');
echo "gethostbyname result: " . $dns_result . "<br>";
}
curl_close($ch);
?>
系统层面的排查
查看系统 DNS 配置
# 查看 /etc/resolv.conf cat /etc/resolv.conf # 检查系统 hosts 文件 cat /etc/hosts # 使用系统命令测试 nslookup example.com dig example.com host example.com
测试不同的 DNS 服务器
# 测试 Google DNS nslookup example.com 8.8.8.8 # 测试 Cloudflare DNS nslookup example.com 1.1.1.1
完整的排查脚本
<?php
class DNSDebugger {
private $domain;
public function __construct($domain) {
$this->domain = $domain;
}
public function runAllTests() {
echo "<h2>DNS Debug Report for: {$this->domain}</h2>";
// 1. 基本DNS查询
$this->testBasicDNS();
// 2. 测试不同记录类型
$this->testRecordTypes();
// 3. 测试解析时间
$this->testResolutionTime();
// 4. 使用gethostbyname
$this->testGethostbyname();
// 5. 查看系统信息
$this->testSystemConfig();
}
private function testBasicDNS() {
echo "<h3>Basic DNS Test:</h3>";
$start = microtime(true);
$ip = gethostbyname($this->domain);
$end = microtime(true);
echo "IP Address: " . $ip . "<br>";
echo "Resolution time: " . number_format(($end - $start) * 1000, 2) . " ms<br>";
if ($ip === $this->domain) {
echo "<span style='color:red'>Failed to resolve domain name!</span><br>";
}
}
private function testRecordTypes() {
echo "<h3>DNS Record Types:</h3>";
$types = [
'DNS_A' => DNS_A,
'DNS_NS' => DNS_NS,
'DNS_MX' => DNS_MX,
'DNS_TXT' => DNS_TXT,
'DNS_SOA' => DNS_SOA
];
foreach ($types as $name => $type) {
$records = @dns_get_record($this->domain, $type);
echo $name . ": ";
if ($records) {
echo "<pre>" . print_r($records, true) . "</pre>";
} else {
echo "No records found or error.<br>";
}
}
}
private function testResolutionTime() {
echo "<h3>Resolution Timing:</h3>";
// 多次测试取平均
$times = [];
for ($i = 0; $i < 5; $i++) {
$start = microtime(true);
dns_get_record($this->domain, DNS_A);
$times[] = microtime(true) - $start;
}
$avg = array_sum($times) / count($times);
$avg_ms = $avg * 1000;
echo "Average resolution time: " . number_format($avg_ms, 2) . " ms<br>";
if ($avg_ms > 100) {
echo "<span style='color:orange'>Warning: Slow DNS resolution detected</span><br>";
}
}
private function testGethostbyname() {
echo "<h3>gethostbyname Test:</h3>";
$result = gethostbyname($this->domain);
echo "Raw result: " . $result . "<br>";
// 检查是否是IP地址
if (filter_var($result, FILTER_VALIDATE_IP)) {
echo "Valid IP address returned.<br>";
// 检查IP类型
if (filter_var($result, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
echo "IPv4 address.<br>";
} elseif (filter_var($result, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
echo "IPv6 address.<br>";
}
} else {
echo "Invalid response - domain might not resolve correctly.<br>";
}
}
private function testSystemConfig() {
echo "<h3>System Configuration:</h3>";
// 显示当前使用的DNS服务器
echo "Resolv.conf: ";
$resolv = file_get_contents('/etc/resolv.conf');
echo nl2br($resolv);
// 显示hosts文件
echo "<br>Hosts file:<br>";
$hosts = file_get_contents('/etc/hosts');
echo nl2br($hosts);
}
}
// 使用示例
$debugger = new DNSDebugger('example.com');
$debugger->runAllTests();
?>
常见问题及解决方案
常见错误代码:
- SERVFAIL:DNS服务器内部错误,需要检查DNS服务器配置
- NXDOMAIN:域名不存在
- TIMEOUT:DNS查询超时
- REFUSED:DNS服务器拒绝查询
优化建议:
- 使用 DNS 缓存:启用
mysqli或PDO的连接持久化 - 配置合适的超时时间:调整
gethostbyname的超时设置 - 使用多个 DNS 服务器:修改
/etc/resolv.conf配置
# 优化 /etc/resolv.conf nameserver 8.8.8.8 nameserver 1.1.1.1 options timeout:2 attempts:3 rotate
通过以上步骤,你可以系统地排查 PHP 的 DNS 问题,并快速定位问题所在。