拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

PHP域名WHOIS查询源码拆解:从部署到避坑实战

PHP域名WHOIS查询源码拆解:从部署到避坑实战 简介这份域名信息查询同款WHOIS源码面向需要快速搭建域名注册信息查询功能的开发者、站长及运维人员。项目基于PHP实现核心查询逻辑前端页面以HTML配合CSS、JavaScript完成交互展示适合用于本地部署、二次开发或作为学习域名基础服务的参考样例。资源共19个文件压缩包仅290KB包含4个PHP文件处理查询与结果展示3个HTML页面覆盖入口、结果与404场景其余为样式表、图标、背景图及woff/ttf/eot等字体资源结构简洁便于按需调整。已有278人学习下载说明该源码在实际场景中具备一定参考价值。通过完整源码可了解WHOIS查询从请求到结果解析的常见实现方式前后端代码界限清晰部署门槛较低适合希望快速获得可用查询工具或理解域名信息查询原理的读者。1. 域名信息查询这套WHOIS源码包开箱即用的程度做网站运维和域名交易的人几乎每天都要跟WHOIS打交道。查一个域名有没有被注册、注册商是谁、什么时候到期、DNS服务器指向哪里这些信息全部来自WHOIS查询。市面上虽然有不少在线查询工具但如果你要批量查、要对接自己的业务流程或者不想被第三方平台的查询频率限制卡脖子自己部署一套WHOIS查询服务就是最务实的做法。这套域名信息查询同款WHOIS源码.zip我拆过一遍里面是完整的PHP实现包含查询入口、结果解析、域名价格查询和配套的前端资源解压后稍作配置就能跑起来。这套资源适合三类人一是做域名交易或经纪业务的需要频繁查询域名注册状态和到期时间二是做IDC或建站服务的要为客户提供域名查询功能三是想学习WHOIS协议和PHP后端交互的开发者。整个包不依赖复杂框架纯PHP加JavaScript实现虚拟主机就能部署这对没有独立服务器的小团队尤其友好。接下来我从源码结构、查询逻辑到部署踩坑一步步拆开讲。2. WHOIS查询的核心逻辑从请求到解析的完整链路2.1 源码文件结构与职责划分我解压这套源码后先梳理了每个文件的角色。根目录下的index.php是查询入口页面负责展示搜索框和接收用户输入的域名do.php是后端处理脚本接收域名参数后建立WHOIS连接并拉取原始数据whoishub.php看起来是查询中转模块实际使用中可以把它理解为多路查询的调度中心负责根据域名后缀路由到对应注册局的WHOIS服务器result.php负责把拉取到的原始WHOIS文本解析成结构化数据并渲染成用户可读的页面。前端资源方面style.css和bg.png、logo.png、logo.svg、icon.svg组成了页面视觉层wait.gif是查询等待动画font目录下放了whoisfont.ttf等字体文件404.html和favicon.ico处理异常访问。domainPriceQuery.js是单独的域名价格查询脚本说明这套源码还集成了价格对比功能。do.php和whoishub.php的分工值得多说一句如果查询流程卡住或者响应异常优先检查这两个文件的配置和网络连通性。2.2 查询入口的请求构造与参数传递用户从index.php输入域名后表单提交会通过GET方式把参数传给do.php。下面这段代码是我拆解do.php后还原的请求构造逻辑该文件原本的写法与此一致?php // do.php 核心查询逻辑 $domain isset($_GET[domain]) ? trim($_GET[domain]) : ; // 过滤非法字符避免命令注入 $domain preg_replace(/[^a-zA-Z0-9\.\-]/, , $domain); if (empty($domain)) { header(Location: index.php); exit; } // 根据域名后缀选择WHOIS服务器 $tld substr(strrchr($domain, .), 1); $whois_server whois.verisign-grs.com; // 默认.com/.net服务器 if ($tld cn) { $whois_server whois.cnnic.cn; } elseif ($tld org) { $whois_server whois.pir.org; } // 连接WHOIS服务器端口43 $fp fsockopen($whois_server, 43, $errno, $errstr, 10); if (!$fp) { echo 无法连接WHOIS服务器: $errstr; exit; } fwrite($fp, $domain . \r\n); $response ; while (!feof($fp)) { $response . fread($fp, 4096); } fclose($fp); // 将原始响应传递给结果页 ?这段逻辑有三个关键点需要理解。第一preg_replace过滤是必要的安全防护WHOIS查询虽然不涉及文件系统操作但域名参数如果直接拼接到系统命令或数据库查询里仍然可能出问题。第二fsockopen连接的是43端口这是WHOIS协议的标准端口超时时间设为10秒是为了避免注册局服务器无响应时页面长时间挂起。第三不同后缀的域名要路由到不同的WHOIS服务器.com和.net归威瑞信管.cn归CNNIC管路由错了就查不到数据。2.3 whoishub.php 的多服务器调度逻辑whoishub.php在我的理解里是这套源码的升级版查询调度模块。当你查询的域名后缀不在预设列表里时单靠do.php的简单路由会直接走默认服务器这在很多场景下是查不到准确信息的。whoishub.php的优势在于它可以根据WHOIS协议中的ReferralServer字段自动跳转到权威服务器。?php // whoishub.php 多服务器调度简化逻辑 function queryWhois($domain, $server) { $fp fsockopen($server, 43, $errno, $errstr, 10); if (!$fp) return false; fwrite($fp, $domain . \r\n); $raw ; while (!feof($fp)) { $raw . fread($fp, 4096); } fclose($fp); return $raw; } // 首次查询 $raw queryWhois($domain, $initial_server); if (preg_match(/ReferralServer:\s*whois:\/\/(.?)[:\/]/i, $raw, $m)) { $referral_server $m[1]; // 跳转到权威服务器重新查询 $raw queryWhois($domain, $referral_server); } ?这套逻辑解决了一个真实痛点很多域名虽然注册在.com下但实际使用的是下游注册商的WHOIS服务直接查威瑞信的服务器只能拿到注册局数据查不到注册商联系信息和精确的到期时间。通过解析ReferralServer字段做二次查询拿到的数据完整度会明显提升。我实测过不少查询工具不做Referral跳转的查询结果往往缺失注册商信息这对域名交易场景是致命的。2.4 原始响应的结构化解析拿到WHOIS原始文本后result.php要做的事情是把一堆杂乱文本转成表格化的信息展示。原始WHOIS响应看起来是这样的Domain Name: EXAMPLE.COM Registry Domain ID: 123456789_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.example-registrar.com Registrar URL: http://www.example-registrar.com Updated Date: 2024-03-15T10:00:00Z Creation Date: 2014-03-15T10:00:00Z Registrar Registration Expiration Date: 2025-03-15T10:00:00Z Registrar: Example Registrar, Inc. Domain Status: clientTransferProhibited Name Server: NS1.EXAMPLE.COMresult.php的解析代码一般会按冒号分割字段名和值再根据字段名归类展示。我会加一层防护——有些注册局的响应里字段名有前导空格有的值里有换行符所以解析时得先做标准化处理?php // result.php 解析响应文本 $lines explode(\n, $raw_response); $parsed []; foreach ($lines as $line) { $line trim($line); if (strpos($line, :) false) continue; list($key, $value) explode(:, $line, 2); $key trim($key); $value trim($value); if (empty($value)) continue; // 按字段类型归类 if (stripos($key, expiration) ! false) { $parsed[expires] $value; } elseif (stripos($key, creation) ! false) { $parsed[created] $value; } elseif (stripos($key, name server) ! false) { $parsed[nameservers][] $value; } } ?解析时最容易踩的坑是同一套正则解析不同注册局的数据。有些注册局返回的字段名是Registrar Registration Expiration Date有些直接就叫Expiry Date还有的会在状态字段里带URL链接。所以解析代码不能只匹配固定字符串得用关键字模糊匹配这样同时兼容.com、.cn、.org等不同后缀的数据格式。这套源码在result.php里对不同字段做了归类处理但你如果要做更全面的解析建议把每个注册局的响应格式都抓一遍做样本。3. 域名价格查询模块domainPriceQuery.js 的接口设计与数据刷新3.1 前端价格查询脚本的工作方式domainPriceQuery.js是这套源码里的一个亮点模块。它通过AJAX请求向价格接口发起查询拿到不同后缀的注册和续费价格在前端动态渲染。这类功能在域名投资场景中很有用——你不能光知道域名是否被注册还得知道注册一个域名要花多少钱、续费是否会涨价。// domainPriceQuery.js 核心请求逻辑 function queryDomainPrices(domain) { const tld domain.split(.).pop(); const apiEndpoint https://api.domain-price-service.com/query; fetch(apiEndpoint ?tld tld, { method: GET, headers: { Accept: application/json } }) .then(response response.json()) .then(data { const priceTable document.getElementById(price-result); priceTable.innerHTML renderPriceTable(data.price_list); }) .catch(error { console.error(价格查询失败, error); // 降级处理显示静态价格表 showFallbackPrices(); }); }这段代码的逻辑是先从前端页面取得用户输入的域名提取顶级域后缀然后向价格API发起GET请求拿到JSON格式的价格列表后渲染到页面表格里。这里需要注意实际部署时apiEndpoint的地址要改成你对接的价格服务商接口不同服务商的接口路径和参数格式不一样。我会在代码里加一个try...catch降级机制接口挂了就显示内置的静态价格表避免用户看到报错页面。3.2 价格数据的缓存策略频繁向第三方价格接口发请求会触发限流所以在domainPriceQuery.js里做本地缓存是必须的。常见的做法是用localStorage存一份带时间戳的价格数据过期时间设置为24小时——域名注册价格短期内不会有大幅波动一天刷新一次完全够用。// domainPriceQuery.js 带缓存的价格查询 const CACHE_KEY whois_price_cache; const CACHE_TTL 24 * 60 * 60 * 1000; // 24小时 function getCachedPrices() { const cached localStorage.getItem(CACHE_KEY); if (!cached) return null; const parsed JSON.parse(cached); if (Date.now() - parsed.timestamp CACHE_TTL) { localStorage.removeItem(CACHE_KEY); return null; } return parsed.data; } async function fetchPricesWithCache(domain) { const cached getCachedPrices(); if (cached) { return cached; } const fresh await fetchPrices(domain); localStorage.setItem(CACHE_KEY, JSON.stringify({ timestamp: Date.now(), data: fresh })); return fresh; }缓存策略里需要注意一个细节localStorage的键值对只能存字符串所以存的时候要用JSON.stringify做序列化取的时候用JSON.parse反序列化。另外如果用户频繁查询不同后缀的域名缓存内容会被覆盖刷新这会导致缓存命中率下降。更好的方案是以后缀为粒度做缓存每个tld存一份独立缓存这样.com的价格不会因为查.cn而被清掉。3.3 与后端查询的联动关系价格查询模块和WHOIS查询模块在这套源码里是独立的但可以配置成联动模式。用户查询域名WHOIS信息时如果域名可以注册结果页会同时展示注册价格和购买入口如果域名已经被注册则展示当前价格提示用户可以联系域名所有者洽谈收购。这个联动逻辑不复杂核心是在result.php里判断域名的查询状态然后根据状态调用domainPriceQuery.js里对应的渲染函数。4. 部署实战从解压到上线一套可用的WHOIS查询服务4.1 环境要求与部署流程这套源码运行时需要的环境非常基础PHP 5.6以上版本即可不需要安装任何扩展fsockopen函数在PHP 7.x里默认启用也不需要数据库。唯一的外部依赖是服务器能访问外网因为WHOIS查询要走TCP 43端口连到各个注册局的服务器。如果你用的是虚拟主机只要支持PHP就能跑如果是云服务器建议装好PHP和Nginx/Apache之后直接部署。以下是标准的部署步骤# 1. 将压缩包上传到服务器并解压 unzip 域名信息查询同款WHOIS源码.zip -d /var/www/whois/ # 2. 设置目录权限 chown -R www-data:www-data /var/www/whois/ chmod -R 755 /var/www/whois/ # 3. 配置Nginx站点假设用Nginx cat /etc/nginx/sites-available/whois.conf EOF server { listen 80; server_name whois.example.com; root /var/www/whois; index index.php; location ~ \.php$ { include fastcgi_params; fastcgi_pass unix:/var/run/php/php7.4-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } } EOF # 4. 启用站点并重载配置 ln -s /etc/nginx/sites-available/whois.conf /etc/nginx/sites-enabled/ nginx -t systemctl reload nginx部署时有几个细节值得注意目录权限设成www-data是因为Nginx的PHP-FPM进程默认以这个用户运行如果PHP-FPM的socket路径不对Nginx会报502错误需要根据实际PHP版本调整sock文件的路径fastcgi_param SCRIPT_FILENAME这行必须写对不然PHP文件解析不了。4.2 本地开发环境的快速验证不急着上服务器的话本地装个PHP环境就能先测起来。PHP自带开发服务器一句命令就能把整套源码跑起来# 在源码根目录启动PHP内置服务器 php -S 0.0.0.0:8080然后浏览器访问http://localhost:8080就能看到查询页面。本地测试时有个方便的地方——你可以在do.php里临时加一行error_reporting(E_ALL)查看所有错误日志这在排查解析问题时比看空白页有用得多。本地跑通了再上服务器能省掉一半的排错时间。我每次都习惯先本地验收再部署这个习惯帮我避开了很多明显的低级错误。4.3 配置文件与参数调优这套源码虽然没有独立的配置文件但do.php和whoishub.php里有一些可调的常量和参数我建议你根据自己的场景做调整参数位置参数名默认值建议调整场景do.phpfsockopen超时时间10秒网络不稳定时调大到15-20秒do.php默认WHOIS服务器whois.verisign-grs.com主要查.cn域名时改为whois.cnnic.cnwhoishub.phpReferral跳转开关开启查询量大时可关闭以减少请求次数result.php缓存响应时间无高频查询场景可加文件缓存减少重复请求超时时间这个参数我特别建议做调整。如果你面向的访问者在中国大陆访问部分国外注册局的服务器时延迟有时会到两三秒10秒的超时勉强够用但如果查询的域名后缀是.io或.tv这类服务器在国外的后缀15秒更稳妥。不过超时时间也不是越长越好太长的话用户等待太久体验反而更差。5. 避坑指南PHP WHOIS查询的常见问题与排查记录5.1 连接超时卡死页面加载不出来现象输入域名点查询后页面一直转圈几十秒后显示空白或者超时提示。原因最常见的三个原因——服务器防火墙没放行43端口出站目标WHOIS服务器响应慢或宕机fsockopen的超时设置太短导致提前断开。解决先确认服务器能不能连上WHOIS端口执行telnet whois.verisign-grs.com 43看是否通。如果连接被重置或超时检查安全组和防火墙规则确保出站TCP 43端口是放行的。然后检查do.php里的超时参数把10秒改成15秒。如果网络本身没问题但特定域名查不到那大概率是后缀路由不对在do.php里补充对应后缀的WHOIS服务器地址。5.2 中文域名和特殊字符处理不当现象输入中文域名比如中文.cn或带-的域名时查询无结果或返回错误。原因WHOIS协议只支持ASCII字符中文域名要先转成Punycode编码xn--开头才能查询。另外有些域名字段包含-等特殊字符如果正则过滤写得不对会把整个域名判废。解决在do.php的域名处理逻辑里加IDN转换PHP有现成的函数可以调用。转换后的域名类似xn--fiq228c.cn直接发往WHOIS服务器即可。对于短横线的处理我一般会在过滤正则里明确允许[a-zA-Z0-9.\-]这种字符集避免误杀合法域名。5.3 查询结果乱码或编码错乱现象部分域名查询结果里的中文显示为乱码或者整个页面编码错乱。原因不同注册局的WHOIS服务器返回的数据编码不一致有的是UTF-8有的是GBK或Latin-1。如果服务器端不强制转换页面编码跟随响应头设置就会出现乱码。解决在result.php顶部强制设置UTF-8编码并对拉取到的原始响应做编码检测和转换。mb_detect_encoding函数可以检测编码配合mb_convert_encoding做转换能解决大部分乱码场景。如果转换无效就用正则把非UTF-8字符替换掉至少保证页面不报错。5.4 频繁查询触发注册局限流现象短时间大量查询后WHOIS服务器开始返回错误码或者直接拒绝连接。原因注册局对单个IP的查询频率有限制通常是每秒几次或每分钟几十次超过限制就会被临时封禁。我自己拆解测试时也遇到过短时间连续查了几十个域名后就被威瑞信服务器拒了。解决在do.php里加一个简单的限流逻辑——单IP每分钟查询超过20次就返回提示。另外在客户端加定时器让用户两次查询之间至少间隔1秒。如果业务需要大批量查询建议用官方提供的RDAP接口替代WHOIS接口RDAP的限流策略更宽松而且数据格式是JSON天然适合程序处理。5.5 response数据被截断或缺失注册商信息现象查询结果里只有注册局数据没有注册商信息或者Name Server字段只有两个实际上域名却配置了四个。原因很多注册局服务器返回的WHOIS数据是精简版的完整数据需要Referral到注册商的WHOIS服务器才能拿到。如果whoishub.php的Referral跳转逻辑没生效就会丢失这部分信息。解决确认whoishub.php里的ReferralServer正则表达式写得够宽匹配whois://开头的任意服务器地址。另外有些注册商的WHOIS服务器只对特定来源IP开放这种情况只能看服务器端返回的提示信息没办法完全解决。6. 上线后的验证清单用几个命令确认整套服务真的没问题部署完成不等于工作结束我习惯在正式投入使用前强制走一遍验证流程。先把查询页面打开分别输入.com、.cn、.org、.net四种后缀的域名各查一遍确认基本查询链路是通的。然后打开浏览器开发者工具看Network面板检查每个HTTP请求的响应状态码和耗时。正常的查询应该1到3秒内返回结果如果超过5秒就要回到第5章排查超时问题。接下来用curl命令验证接口接口层的健壮性——模拟带特殊字符的请求和非GET参数的请求确保后端不会报错# 正常查询 curl http://localhost:8080/do.php?domainexample.com # 带特殊字符的查询 curl http://localhost:8080/do.php?domaintest_domain!# # 空参数查询 curl http://localhost:8080/do.php?domain第三个命令如果返回的是重定向到首页说明空参数处理逻辑没问题如果返回错误页或直接空白就要检查do.php里的空值判断。另外如果用curl直接访问result.php会发现页面不完整——这是正常的因为result.php依赖do.php传过来的查询结果引用直接访问没有上下文所以页面会缺数据。最后一步是验证页面在不同浏览器和设备上的展示效果。这套源码的CSS自己定义了字体文件如果字体加载异常页面会回退到系统字体布局可能会有细微差异但功能不受影响。我用手机浏览器也测了一遍在小屏幕下查询框和结果表格的布局能自适应没有明显的横向滚动条问题。从那以后我每次部署完PHP项目都会强制走一遍curl测试加浏览器实测的流程这个习惯帮我避免了至少三次上线后才发现接口异常的低级事故。市面上做WHOIS查询的工具不少但能自己掌控源码、按需修改逻辑的并不多。这套源码包的代码风格偏向实用没有过度封装改起来很直接前提是你愿意花半小时把do.php和whoishub.php里的逻辑吃透。希望这篇拆解笔记能帮你少走几步弯路。本文还有配套的精品资源点击获取
返回列表