PHP 內建 checkdnsrr() 僅在 Linux/Unix 平台可用(依賴系統解析器)。Windows 環境下調用會報錯 Call to undefined function checkdnsrr(),導致跨平台代碼兼容性問題。
利用 Windows 系統命令 nslookup 解析 DNS 記錄,封裝為同名函數:
if (!function_exists('checkdnsrr')) {
/**
* Windows 相容的 checkdnsrr 實現
* @param string $host 主機名或 IP
* @param string $type 記錄類型 (A, MX, TXT, CNAME, AAAA 等)
* @return bool 記錄是否存在
*/
function checkdnsrr($host, $type = 'A') {
if (empty($host) || empty($type)) return false;
// 構建 nslookup 命令,逃逸參數防注入
$cmd = 'nslookup -type=' . escapeshellarg($type) . ' ' . escapeshellarg($host);
// 執行命令捕獲輸出
@exec($cmd, $output);
// 解析輸出:尋找以查詢主機名開頭的行
foreach ($output as $line) {
if (preg_match('/^' . preg_quote($host, '/') . '/i', $line)) {
return true;
}
}
return false;
}
}
function_exists() 守衛:僅在原生函數不存在時定義,不影響 Linux 環境。escapeshellarg():防止命令注入,確保參數安全。@exec() 抑制警告:nslookup 找不到記錄時返回非零碼,不應視為錯誤。/^host/i:匹配輸出中以查詢主機名開頭的行(如 example.com address = 93.184.216.34),避免誤匹配權威服務器資訊。// 測試 A 記錄
var_dump(checkdnsrr('google.com', 'A')); // true
var_dump(checkdnsrr('nonexistent.invalid', 'A')); // false
// 測試 MX 記錄(郵件服務器)
var_dump(checkdnsrr('gmail.com', 'MX')); // true
// 測試 TXT 記錄(SPF/DKIM)
var_dump(checkdnsrr('google.com', 'TXT')); // true
| 方案 | 優點 | 缺點 |
|---|---|---|
| nslookup 封裝(本文) | 零依賴、跨平台、代碼簡潔 | 依賴系統命令、解析輸出較脆弱、效能一般 |
| dns_get_record() | PHP 內建、返回結構化數組、支援多記錄類型 | Windows PHP 5.3+ 才支援、舊版不可用 |
| Net_DNS2 (PEAR) | 純 PHP 實現、功能完整、無系統依賴 | 需安裝套件、佔用記憶體 |
| ReactPHP DNS | 異步非阻塞、高併發友好 | 架構複雜、學習曲線陡峭 |
dns_get_record(),功能更強且標準化。nslookup)。