Skip to content

Instantly share code, notes, and snippets.

@anzz1
Last active December 3, 2025 18:45
Show Gist options
  • Select an option

  • Save anzz1/319f6c34ffec981a70e43dfad0629f89 to your computer and use it in GitHub Desktop.

Select an option

Save anzz1/319f6c34ffec981a70e43dfad0629f89 to your computer and use it in GitHub Desktop.
whois.php
<?php
/* Simple PHP WHOIS (PHP >= 4.0) */
/* https://gist.github.com/anzz1 */
/* --------------------- CONFIGURATION --------------------- */
// Clean up comments ('#', '%') and empty lines from the response
$NO_COMMENTS = false;
// Use IANA lookup for TLDs which are not on the list below at the cost of an additional query
$USE_IANA_LOOKUP = false;
// Allow querying UTF-8 internationalized domain names, disable to validate domains as US-ASCII
//
// This feature requires either enabling the 'php-intl' module or adding 'idna.class.php'
// polyfill to the script directory (idna.class.php: https://gist.github.com/anzz1)
$ALLOW_INTL_DOMAINS = false;
// Every WHOIS server which does not follow "whois.nic.tld" paradigm should be added here
//
// For the full list of TLDs see: http://www.iana.org/domains/root/db/
// http://www.whois365.com/en/listtld/
//
// WHOIS servers can be queried from IANA WHOIS: http://www.iana.org/whois
$WHOIS_SERVERS = array(
"aero" => array("whois.aero", true),
"al" => array("whois.ripe.net", true), // Albania
"am" => array("whois.amnic.net", true), // Armenia
"arpa" => array("whois.iana.org", true),
"au" => array("whois.aunic.net", true), // Australia
"ax" => array("whois.ax", true), // Aland Islands
"az" => array("whois.ripe.net", true), // Azerbaijan
"be" => array("whois.dns.be", true), // Belgium
"bg" => array("whois.register.bg", true), // Bulgaria
"biz" => array("whois.biz", true),
"bn" => array("whois.bn", true), // Brunei Darussalam
"br" => array("whois.registro.br", false), // Brazil
"bt" => array("whois.netnames.net", true), // Bhutan
"by" => array("whois.cctld.by", true), // Belarus
"bz" => array("whois.belizenic.bz", true), // Belize
"ca" => array("whois.cira.ca", true), // Canada
"cat" => array("whois.cat", true), // Spain (Catalonia)
"cn" => array("whois.cnnic.net.cn", true), // China
"cy" => array("whois.ripe.net", true), // Cyprus
"com" => array("whois.verisign-grs.com", true),
"de" => array("whois.denic.de", true), // Germany
"dk" => array("whois.dk-hostmaster.dk", true), // Denmark
"dz" => array("whois.ripe.net", true), // Algeria
"edu" => array("whois.educause.edu", true),
"ee" => array("whois.eenet.ee", true), // Estonia
"eg" => array("whois.ripe.net", true), // Egypt
"eu" => array("whois.eu", true), // European Union
"fi" => array("whois.ficora.fi", false), // Finland
"gg" => array("whois.gg", true), // Guernsey
"gi" => array("whois2.afilias-grs.net", true), // Gibraltar
"gm" => array("whois.ripe.net", true), // Gambia
"gy" => array("whois.registry.gy", true), // Guyana
"hk" => array("whois.hkirc.hk", true), // Hong Kong
"hm" => array("whois.registry.hm", true), // Heard and MacDonald Islands, Australia
"hn" => array("whois2.afilias-grs.net", true), // Honduras
"hr" => array("whois.dns.hr", true), // Croatia
"hu" => array("whois.nic.hu", true), // Hungary
"ie" => array("whois.domainregistry.ie", true), // Ireland
"il" => array("whois.isoc.org.il", true), // Israel
"in" => array("whois.inregistry.net", true), // India
"info" => array("whois.afilias.net", true),
"int" => array("whois.iana.org", true),
"iq" => array("whois.cmc.iq", true), // Iraq
"is" => array("whois.isnic.is", false), // Iceland
"je" => array("whois.je", true), // Jersey
"jobs" => array("jobswhois.verisign-grs.com", true),
"jp" => array("whois.jprs.jp", true), // Japan
"ke" => array("whois.kenic.or.ke", true), // Kenya
"kg" => array("www.domain.kg", true), // Kyrgyzstan
"kr" => array("whois.kr", true), // Korea, Republic Of
"lt" => array("whois.domreg.lt", true), // Lithuania
"lu" => array("whois.dns.lu", false), // Luxembourg
"ma" => array("whois.iam.net.ma", true), // Morocco
"mc" => array("whois.ripe.net", true), // Monaco
"mo" => array("whois.monic.mo", true), // Macao
"mobi" => array("whois.dotmobiregistry.net", true),
"museum" => array("whois.museum", true),
"mx" => array("whois.mx", true), // Mexico
"my" => array("whois.domainregistry.my", true), // Malaysia
"na" => array("whois.na-nic.com.na", true), // Namibia
"nc" => array("whois.nc", true), // New Caledonia
"net" => array("whois.verisign-grs.net", true),
"ng" => array("whois.nic.net.ng", true), // Nigeria
"nl" => array("whois.domain-registry.nl", true), // Netherlands
"no" => array("whois.norid.no", false), // Norway
"nz" => array("whois.srs.net.nz", true), // New Zealand
"om" => array("whois.registry.om", true), // Oman
"org" => array("whois.pir.org", true),
"pe" => array("kero.yachay.pe", true), // Peru
"pf" => array("whois.registry.pf", true), // French Polynesia
"pl" => array("whois.dns.pl", true), // Poland
"post" => array("whois.dotpostregistry.net", true),
"pro" => array("whois.dotproregistry.net", true),
"pt" => array("whois.dns.pt", true), // Portugal
"qa" => array("whois.registry.qa", true), // Qatar
"ro" => array("whois.rotld.ro", true), // Romania
"rs" => array("whois.rnids.rs", true), // Serbia
"ru" => array("whois.tcinet.ru", true), // Russian Federation
"sa" => array("whois.nic.net.sa", true), // Saudi Arabia
"sb" => array("whois.nic.net.sb", true), // Solomon Islands
"sc" => array("whois2.afilias-grs.net", true), // Seychelles
"se" => array("whois.iis.se", true), // Sweden
"sg" => array("whois.sgnic.sg", true), // Singapore
"si" => array("whois.arnes.si", true), // Slovenia
"sk" => array("whois.sk-nic.sk", true), // Slovakia
"su" => array("whois.tcinet.ru", true), // Russian Federation
"sx" => array("whois.sx", true), // Sint Maarten (Dutch)
"sy" => array("whois.tld.sy", true), // Syrian Arab Republic
"tc" => array("whois.meridiantld.net", true), // Turks And Caicos Islands
"th" => array("whois.thnic.co.th", true), // Thailand
"tk" => array("whois.dot.tk", true), // Tokelau
"tn" => array("whois.ati.tn", true), // Tunisia
"to" => array("whois.tonic.to", true), // Tonga
"tp" => array("whois.nic.tl", true), // Timor-leste
"tv" => array("tvwhois.verisign-grs.com", true), // Tuvalu
"tw" => array("whois.twnic.net.tw", true), // Taiwan
"tz" => array("whois.tznic.or.tz", true), // Tanzania, United Republic Of
"ua" => array("whois.ua", true), // Ukraine
"ug" => array("whois.co.ug", true), // Uganda
"uy" => array("whois.nic.org.uy", true), // Uruguay
"uz" => array("whois.cctld.uz", true), // Uzbekistan
"va" => array("whois.ripe.net", true), // Vatican (Holy See)
"vc" => array("whois2.afilias-grs.net", true), // Saint Vincent And The Grenadines
"vg" => array("whois.adamsnames.tc", true), // Virgin Islands, British
"vu" => array("vunic.vu", true), // Vanuatu
"ws" => array("whois.website.ws", true), // Samoa
"yu" => array("whois.ripe.net", true) // Yugoslavia, Former
);
/* --------------------------------------------------------- */
@ini_set("default_charset", "utf-8");
$query = (isset($_GET['q']) ? $_GET['q'] : null);
$txt = (isset($_GET['txt']) ? $_GET['txt'] : false);
$errors = array();
if ($ALLOW_INTL_DOMAINS) {
if (!function_exists("idn_to_ascii")) {
if ((@include("idna.class.php")) == false || !function_exists("idn_to_ascii")) {
die("ERROR: idn_to_ascii() function missing!\n");
}
}
function GetIDN($domain) { return idn_to_ascii($domain); }
function ValidateDomain($domain) {
if ($idn = GetIDN($domain)) {
$len = strlen($idn);
return (($len > 2 && $len < 64) ? $domain : false);
}
return false;
}
}
else {
function GetIDN($domain) { return $domain; }
function ValidateDomain($domain) {
return ((preg_match("/^([-a-z0-9]{2,100})\.([a-z\.]{2,20})$/i", $domain) === 1) ? $domain : false);
}
}
function LookupWhois($domain) {
$result = QueryWhoisServer("whois.iana.org", $domain, true);
if (empty($result)) return null;
if (preg_match("/.*refer:\h*([^\s\/]+)/i", $result, $matches) === 1) return $matches[1];
if (preg_match("/.*whois:\h*([^\s\/]+)/i", $result, $matches) === 1) return $matches[1];
return null;
}
function LookupDomain($domain) {
$domain_parts = explode(".", $domain);
$tld = strtolower(array_pop($domain_parts));
$whoisserver = @$GLOBALS["WHOIS_SERVERS"][$tld];
if ($whoisserver) {
$server = $whoisserver[0];
$is_utf8 = $whoisserver[1];
}
else {
$is_utf8 = true;
if ($GLOBALS["USE_IANA_LOOKUP"]) $server = LookupWhois($domain); // lookup from IANA
if (empty($server)) $server = "whois.nic.$tld";
}
$results = array();
while ($results[$server] = QueryWhoisServer($server, $domain, $is_utf8)) {
if (preg_match("/.*whois server:\h*([^\s\/]+)/i", $results[$server], $matches) !== 1) break;
$server = $matches[1];
if (empty($server) || isset($results[$server])) break;
}
return array_filter($results);
}
function LookupIP($ip) {
$whoisservers = array(
array("whois.arin.net", "n ", "ReferralServer:"), // North America only
array("whois.ripe.net", "", "NON-RIPE-NCC-MANAGED-ADDRESS-BLOCK"), // Europe, Middle East and Central Asia only
array("whois.apnic.net", "", "This network range is not allocated to APNIC"), // Asia-Pacific only
array("whois.lacnic.net", "", "ReferralServer:"), // Latin America and Caribbean
array("whois.afrinic.net", "", "ALLOCATED UNSPECIFIED") // Africa
);
foreach ($whoisservers as $whoisserver) {
$result = QueryWhoisServer($whoisserver[0], $whoisserver[1].$ip, false);
if (!empty($result) && (strpos($result, $whoisserver[2]) === false)) return array($whoisserver[0] => $result);
}
return array();
}
function QueryWhoisServer($whoisserver, $query, $is_utf8) {
$port = 43;
$timeout = 10;
$data = null;
$errstr = "";
$fp = @fsockopen($whoisserver, $port, $errno, $errstr, $timeout);
if ($fp === false) $GLOBALS["errors"][] = "$whoisserver connection error: $errstr";
else {
@socket_set_timeout($fp, $timeout);
if (@fputs($fp, "$query\r\n") === false) $GLOBALS["errors"][] = "$whoisserver connection error: $errstr";
else {
$data = "";
$r = array($fp);
$w = null;
while (is_resource($fp) && !feof($fp)) {
if (function_exists("stream_select")) {
if (!@stream_select($r, $w, $w, $timeout)) {
fclose($fp);
$GLOBALS["errors"][] = "$whoisserver connection error: Connection timed out";
return null;
}
}
$data .= fgets($fp);
if (function_exists("stream_get_meta_data")) {
$info = @stream_get_meta_data($fp);
if (is_array($info) && $info["timed_out"]) {
fclose($fp);
$GLOBALS["errors"][] = "$whoisserver connection error: Connection timed out";
return null;
}
}
}
$rows = explode("\n", ($is_utf8 ? $data : utf8_encode($data)));
$data = "";
$clean = $GLOBALS["NO_COMMENTS"];
foreach ($rows as $row) {
$row = trim($row);
if (strncmp($row, "Timeout", 7) === 0) {
fclose($fp);
$GLOBALS["errors"][] = "$whoisserver query error: Request timed out";
return null;
}
if (!$clean || (!empty($row) && ($row[0] != '#') && ($row[0] != '%'))) $data .= "$row\n";
}
}
fclose($fp);
}
return $data;
}
function ValidateIP($ip) {
$ipnums = explode(".", $ip);
if (count($ipnums) != 4) return false;
foreach ($ipnums as $ipnum) {
if (!is_numeric($ipnum) || ($ipnum > 255) || ($ipnum < 0)) return false;
}
return $ip;
}
function TrimDomain($domain) {
$domain = trim($domain);
$start = strpos(strtolower($domain), "://");
if ($start !== false) $start += 3;
$end = strpos(strtolower($domain), "/", $start);
if ($end !== false) $domain = substr($domain, $start, $end-$start);
elseif ($start !== false) $domain = substr($domain, $start);
if (strncmp(strtolower($domain), "www.", 4) === 0) $domain = substr($domain, 4);
return $domain;
}
function PrintResults($what, $query, $results) {
if ($results) {
$res = "";
foreach ($results as $whoisserver => $result) {
$res .= "\n\n-------------\n$what results for $query from $whoisserver [".@gethostbyname(GetIDN($whoisserver))."]:\n\n$result";
}
return $res;
}
return "\n\n-------------\nNo results for $query";
}
function PrintErrors($errors) {
if ($errors) {
$res = "\n\n-------------";
foreach ($errors as $err) {
$res .= "\n$err";
}
return $res;
}
return "";
}
if ($query) $query = TrimDomain($query);
if ($txt) header("Content-Type: text/plain; charset=utf-8");
else {
header("Content-Type: text/html; charset=utf-8");
?>
<!DOCTYPE html>
<html>
<head>
<title><?=($query ? "WHOIS Lookup for $query" : "WHOIS Lookup");?></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style>
* {
color: #e8e6e3;
color-scheme: dark;
background-color: #181a1b;
border-color: #736b5e;
scrollbar-color: #454a4d #202324;
}
#q:focus {
outline: none !important;
}
</style>
<script>
if (window.history.replaceState) {
window.history.replaceState(null, null, window.location.href);
}
</script>
</head>
<body>
<form action="<?=$_SERVER['PHP_SELF'];?>">
<p><b><label for="q">Domain/IP Address:</label></b> <input type="text" name="q" id="q" placeholder="google.com" value="<?=$query;?>"> <input type="submit" value="Lookup"></p>
</form>
<pre>
<?php
}
if ($query) {
if (ValidateIP($query)) {
echo "IP: $query";
echo "\nRDNS: ".@gethostbyaddr($query);
$res = PrintResults("IP-Lookup", $query, LookupIP($query));
echo PrintErrors($errors);
echo $res;
}
elseif (ValidateDomain($query)) {
echo "DOMAIN: $query";
$idn = GetIDN($query);
if ($idn !== $query) echo "\nIDN: $idn";
$ip = ValidateIP(@gethostbyname($idn));
echo "\nIP: $ip";
echo "\nRDNS: ".($ip ? @gethostbyaddr($ip) : "");
$res = PrintResults("WHOIS", $query, LookupDomain($query));
if ($ip) $res .= PrintResults("IP-Lookup", $ip, LookupIP($ip));
echo PrintErrors($errors);
echo $res;
}
else echo "Invalid Input!";
}
if (!$txt) {
?>
</pre>
</body>
</html>
<?php } ?>
@anzz1
Copy link
Author

anzz1 commented Oct 17, 2024

Thanks @ehnwebmaster , added the missing ones.
Some of them were redundant, note that the script automatically defaults to whois.nic.TLD for domains not on the list so those do not need to be added.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment