The Ultimate PHP WhoIs Parsing Code – Jafty Whois

As far as I am concerned, this is the holy grail of PHP Whois apps and I have tried a lot of them. I of course had to make my own to get what I wanted, but I used what I took in from experimenting with all the popular choices out today to come up with JAFTY WHOIS.

The trick was to keep it as simple as possible and get it to run as many consecutive queries as possible. The purpose of the code is to fetch Whois data for a quantity of domain names. It gets such data as the domain owner’s email address, contact information, expire and creation date.

The Code

I developed the ultimate Jafty Whois code with two key functions. The first is called “queryWhois” and is the function that does the actual query to the whois server. The second function, called “runDom”, basically runs the “queryWhois” function. The job of the “runDom” function is to monitor the “queryWhois” function and sometimes run it again based on what it returns.

Here are the two functions as they are in the working demo (Contact Ian at linian11@yahoo.com for complete demo code):

function queryWhois($domain,$whoisserver = “whois.verisign-grs.com”) {
$port = 43;
$timeout = 10;
$fp = @fsockopen($whoisserver, $port, $errno, $errstr, $timeout) or die(“fsocketopen Error ” . $errno . ” – ” . $errstr);
fputs($fp, $domain . “\r\n”);
$out = “”;
    while(!feof($fp)){
    $out .= fgets($fp);
    }
fclose($fp);
$res = “”;
    if((strpos(strtolower($out), “error”) === FALSE) && (strpos(strtolower($out), “not allocated”) === FALSE)) {
    $rows = explode(“\n”, $out);
        foreach($rows as $row) {
        $row = trim($row);
            if(($row != ”) && ($row{0} != ‘#’) && ($row{0} != ‘%’)) {
            $res .= $row.”\n”;
            }
        }
    }
return $res;
}//end queryWhois function.

function runDom($domain){
$whoisserver = “.com”;//just for showing note below, not actual server…
$result = queryWhois($domain);
    if(!$result){
    return “Error: No results found for $domain!”;
    }else{
    //look for “Whois Server:” indicating we need to get results from a diff server:
        while(strpos($result, “Whois Server:”) !== FALSE){
        preg_match(“/Whois Server: (.*)/”, $result, $matches);
        $secondary = $matches[1];
            if($secondary) {
            $result = queryWhois($domain,$secondary);
            $whoisserver = $secondary;
            }
        }//end while looking for secondary whois server.
    }
return “<h2>$domain results from $whoisserver server:</h2>” . $result;
}//end runDom function

Why does the queryWhois function need monitored?

Great question and that’s the secret to this code’s success. Lets take the raw queryWhois function and run it by itself without the “runDom” functon and see what happens. There are two likely scenarios, the first will return standard whois results and that’s fine, but the second will return something like the below example. That’s bad because it doesn’t contain the whois data we are ultimately looking for! However, it does contain the key to getting that data. It contains the whois server you need to query instead. This is done with the queryWhois function too, but it needs to be told to run again with the a different whois server, so in comes the “runDom” function to tell it to run again when this secondary whois server is spotted, passing that whois server URL as a variable to the queryWhois function like: queryWhois($domain, $serverURL). The $serverURL variable would be set to the new whois server found while running the queryWhois function the first time.

Example results of queryWhois function when a secondary whois server is found instead of domain name’s whois data:

——————–Start queryWhois test results——————

Whois Server Version 2.0
Domain names in the .com and .net domains can now be registered
with many different competing registrars. Go to http://www.internic.net
for detailed information.
Domain Name: AAAX.COM
Registrar: DOMAIN.COM, LLC
Whois Server: whois.domain.com
Referral URL: http://www.domain.com
Name Server: NS1.SEDOPARKING.COM
Name Server: NS2.SEDOPARKING.COM
Status: clientTransferProhibited
Status: clientUpdateProhibited
Updated Date: 18-nov-2013
Creation Date: 01-dec-1999
Expiration Date: 01-dec-2014
>>> Last update of whois database: Sun, 18 May 2014 06:40:14 UTC <<<
NOTICE: The expiration date displayed in this record is the date the...*

———————End queryWhois test results—————-

*NOTE:  where you see …* at the end of the above test results, I shortened the results because the remaining text was irrelevant for this demonstration.

Notice in the above example test results where I highlighted the whois server text in orange bold text. That is what the runDom function searches for, and if the text “whois server:” is found, it knows to rerun the queryWhois function a second time using the whois server named after the colon.

Example results of runDom function controlling the queryWhois function so that it runs secondary Whois server found during first run of queryWhois function:

————————Start test results——————–

Domain Name:

aaax.com results from whois.domain.com server:

Domain Name: AAAX.COM
Registry Domain ID:
Registrar WHOIS Server: whois.domain.com
Registrar URL: www.domain.com
Updated Date: 2013-11-18 09:04:07
Creation Date: 1999-12-01 15:20:53
Registrar Registration Expiration Date: 2014-12-01 15:20:53
Registrar: Domain.com, LLC
Registrar IANA ID: 886
Registrar Abuse Contact Email: compliance@domain-inc.net
Registrar Abuse Contact Phone: +1.6027165396
Reseller: MyDomain
Reseller: support@mydomain-inc.com
Reseller: +1.8004057875
Domain Status: clientTransferProhibited
Domain Status: clientUpdateProhibited
Registry Registrant ID:
Registrant Name: TODD BERNHARD
Registrant Organization: Domain Owner
Registrant Street: 20 Barclay Square Drive
Registrant City: Rochester
Registrant State/Province: NY
Registrant Postal Code: 14618
Registrant Country: US
Registrant Phone: 585475.1030
Registrant Phone Ext:
Registrant Fax: 585475.1030
Registrant Fax Ext:
Registrant Email: domain@hqlabs.com
Registry Admin ID:
Admin Name: TODD BERNHARD
Admin Organization: Domain Owner
Admin Street: 20 Barclay Square Drive
Admin City: Rochester
Admin State/Province: NY
Admin Postal Code: 14618
Admin Country: US
Admin Phone: 585475.1030
Admin Phone Ext:
Admin Fax: 585475.1030
Admin Fax Ext:
Admin Email: domain@hqlabs.com
Registry Tech ID:
Tech Name: TODD BERNHARD
Tech Organization: Domain Owner
Tech Street: 20 Barclay Square Drive
Tech City: Rochester
Tech State/Province: NY
Tech Postal Code: 14618
Tech Country: US
Tech Phone: 585475.1030
Tech Phone Ext:
Tech Fax: 585475.1030
Tech Fax Ext:
Tech Email: domain@hqlabs.com
Name Server: NS1.SEDOPARKING.COM
Name Server: NS2.SEDOPARKING.COM
DNSSEC: Unsigned
URL of the ICANN WHOIS Data Problem Reporting System: http://wdprs.internic.net/
>>> Last update of WHOIS database: 2013-11-18 09:04:07 <<<
Registration Service Provider:
MyDomain, support@mydomain-inc.com
+1.8004057875
This company may be contacted for domain login/passwords,
DNS/Nameserver changes, and general domain support questions.

————————-End test results———————

Summary

Sometimes the queryWhois function will return the results the first time and doesn’t need the runDom function to extract the secondary whois server and rerun it. So, it should be noted that sometimes it returns results and sometimes it returns a string of text that most likely contains the actual whois server to query for the domain name passed to it. Without the important runDom function, the queryWhois function would only work approximately one out of five times. If you require assistance with Jafty Whois or would like a custom application built based on it, contact Ian L. of Jafty.com at linian11@yahoo.com

2 Replies to “The Ultimate PHP WhoIs Parsing Code – Jafty Whois”

  1. Awesome! Works like a charm.
    Is there a limit to the number of requests I can make per second? I want to put this in a for loop and run through dozens if not hundreds of domains.

  2. very useful, thanks. Main problem related to WHOIS queries is related on TLD diversification on format, i.e there is not standard and would be fine otherwise. Happy programming 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *