Regan Johnson - Web Design, Marketing, SEO

PHP Domain Availability Lookup

The process to check if a domain name is registered or not usually involves a series of steps that can be tedious and time consuming. In this article, I will show you how to create your own domain name availability script using PHP that you may use in your personal projects – it’s much easier than you might think.

Building the Domain Name Availability class

For the sake of this article, let’s call this class “whois”.

class whois {

}

One of the first things we are going to add to our class is a list of the common TLD, which will include which whois server to use for each domain, and the associated text to search for if a domain is available or not. The array is named “$ext” which is short for extensions.

public $ext = array(
'.com' => array('whois.crsnic.net','No match for'),
'.net' => array('whois.crsnic.net','No match for'),
'.org' => array('whois.publicinterestregistry.net','NOT FOUND'),
'.us' => array('whois.nic.us','Not Found'),
'.biz' => array('whois.biz','Not found'),
'.info' => array('whois.afilias.net','NOT FOUND'),
'.eu' => array('whois.eurid.eu','FREE'),
'.mobi' => array('whois.dotmobiregistry.net', 'NOT FOUND'),
'.tv' => array('whois.nic.tv', 'No match for'),
'.in' => array('whois.inregistry.net', 'NOT FOUND'),
'.co.uk' => array('whois.nic.uk','No match'),
'.co.ug' => array('wawa.eahd.or.ug','No entries found'),
'.or.ug' => array('wawa.eahd.or.ug','No entries found'),
'.sg' => array('whois.nic.net.sg','NOMATCH'),
'.com.sg' => array('whois.nic.net.sg','NOMATCH'),
'.per.sg' => array('whois.nic.net.sg','NOMATCH'),
'.org.sg' => array('whois.nic.net.sg','NOMATCH'),
'.com.my' => array('whois.mynic.net.my','does not Exist in database'),
'.net.my' => array('whois.mynic.net.my','does not Exist in database'),
'.org.my' => array('whois.mynic.net.my','does not Exist in database'),
'.edu.my' => array('whois.mynic.net.my','does not Exist in database'),
'.my' => array('whois.mynic.net.my','does not Exist in database'),
'.nl' => array('whois.domain-registry.nl','not a registered domain'),
'.ro' => array('whois.rotld.ro','No entries found for the selected'),
'.com.au' => array('whois.ausregistry.net.au','No data Found'),
'.ca' => array('whois.cira.ca', 'AVAIL'),
'.org.uk' => array('whois.nic.uk','No match'),
'.name' => array('whois.nic.name','No match'),
'.ac.ug' => array('wawa.eahd.or.ug','No entries found'),
'.ne.ug' => array('wawa.eahd.or.ug','No entries found'),
'.sc.ug' => array('wawa.eahd.or.ug','No entries found'),
'.ws' => array('whois.website.ws','No Match'),
'.be' => array('whois.ripe.net','No entries'),
'.com.cn' => array('whois.cnnic.cn','no matching record'),
'.net.cn' => array('whois.cnnic.cn','no matching record'),
'.org.cn' => array('whois.cnnic.cn','no matching record'),
'.no' => array('whois.norid.no','no matches'),
'.se' => array('whois.nic-se.se','No data found'),
'.nu' => array('whois.nic.nu','NO MATCH for'),
'.com.tw' => array('whois.twnic.net','No such Domain Name'),
'.net.tw' => array('whois.twnic.net','No such Domain Name'),
'.org.tw' => array('whois.twnic.net','No such Domain Name'),
'.cc' => array('whois.nic.cc','No match'),
'.nl' => array('whois.domain-registry.nl','is free'),
'.pl' => array('whois.dns.pl','No information about'),
'.pt' => array('whois.dns.pt','No match')
);

We will also define our error variable that we will be using in this class.

public $error;

Building the Methods

Now that we have our class ready to go, and our list of domain name extensions and associated WHOIS servers, lets build the function to use this information to perform the domain name lookup.

function available($domain){
$domain = trim($domain);
if (eregi('^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)*[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?$',$domain) != 1){
$error = 'Invalid domain (Letters, numbers and hypens only) ('.$domain.')';
return false;
}
preg_match('@^(http://www\.|http://|www\.)?([^/]+)@i', $domain, $preg_metch_result);
$f_result = '';
$domain = $preg_metch_result[2];
$domain_name_array = explode('.', $domain);
$domain_domain = strtolower(trim($domain_name_array[count($domain_name_array)-1]));
$ext_in_list = false;

if (array_key_exists('.'.$domain_domain, $this->ext)){
$ext_in_list = true;
}

if(strlen($domain) > 0 && $ext_in_list){
$server = '';

$server = $this->ext['.' .$domain_domain][0];
$lookup_result = gethostbyname($server);

if ($lookup_result == $server){
$error = 'Error: Invalid extension - '.$domain_domain.'. / server has outgoing connections blocked to '.$server.'.';
return false;
}

$fs = fsockopen($server, 43,$errno,$errstr,10);
if (!$fs || ($errstr != "")){
$error = 'Error: ('.$server.') '.$errstr.' ('.$errno.')';
return false;
}

fputs($fs, "$domain\r\n");
while( !feof($fs) ) {
$f_result .= fgets($fs,128);
}

fclose($fs);

if($domain_domain == 'org'){
nl2br($f_result);
}

if(eregi($this->ext['.'.$domain_domain][1], $f_result)){
return true;
} else {
return false;
}

} else {
$error = 'Invalid Domain and/or TLD server entry does not exist';
}
return false;
}

Going through the method

I will explain each piece of this method in case you would like to know exactly what is going on.

  $domain = trim($domain);
if (eregi('^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)*[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?$',$domain) != 1){
$error = 'Invalid domain (Letters, numbers and hypens only) ('.$domain.')';
return false;
}

Here we are trimming excess whitespace from the domain, and checking to make sure that it conforms to standards. (Checking if the domain is in a valid format). If it is invalid, we give an error, and return false.

  preg_match('@^(http://www\.|http://|www\.)?([^/]+)@i', $domain, $preg_metch_result);
$f_result = '';
$domain = $preg_metch_result[2];
$domain_name_array = explode('.', $domain);
$domain_domain = strtolower(trim($domain_name_array[count($domain_name_array)-1]));
$ext_in_list = false;

if (array_key_exists('.'.$domain_domain, $this->ext)){
$ext_in_list = true;
}

In this block of code, we are splitting the domain name into it’s respective parts (domain, extension) and checking to see that the extension (TLD) is in the list that we defined earlier. We set a variable “$ext_in_list” to true if it is.

  if(strlen($domain) > 0 && $ext_in_list){

We make sure that the extension is in the list, and the domain is at least 1 character long.

  $server = '';
$server = $this->ext['.' .$domain_domain][0];
$lookup_result = gethostbyname($server);

if ($lookup_result == $server){
$error = 'Error: Invalid extension - '.$domain_domain.'. / server has outgoing connections blocked to '.$server.'.';
return false;
}

In this block of code, we get the corresponding WHOIS server from our predefined list, and get the IP address associated with that server. If the result of the IP lookup is false, we assume that the server is blocking our connection or that the extension is invalid. If not, we assume the lookup was successful and valid.

  $fs = fsockopen($server, 43,$errno,$errstr,10);
if (!$fs || ($errstr != "")){
$error = 'Error: ('.$server.') '.$errstr.' ('.$errno.')';
return false;
}

fputs($fs, "$domain\r\n");
while( !feof($fs) ) {
$f_result .= fgets($fs,128);
}

fclose($fs);

if($domain_domain == 'org'){
nl2br($f_result);
}

Here we open a new socket connection on port 43. If the connection fails, we handle the error, and return the method false. If it succeeds, we continue to retrieve result from the socket connection. Once the result is retrieve, we close the connection, and preform some formatting on the results should the domain name be a “.org”.

  if(eregi($this->ext['.'.$domain_domain][1], $f_result)){
return true;
} else {
return false;
}

} else {
$error = 'Invalid Domain and/or TLD server entry does not exist';
}
return false;
}

The last block of code will check our extension array defined earlier to see if the result matches the text provided for that specified extension. If the there is a match, we return true, otherwise, we return false.

Putting it all together

Now that we know how the class and method works, lets put it all together, and give an example on how to use it in your script.

class whois {

public $ext = array(
'.com' => array('whois.crsnic.net','No match for'),
'.net' => array('whois.crsnic.net','No match for'),
'.org' => array('whois.publicinterestregistry.net','NOT FOUND'),
'.us' => array('whois.nic.us','Not Found'),
'.biz' => array('whois.biz','Not found'),
'.info' => array('whois.afilias.net','NOT FOUND'),
'.eu' => array('whois.eurid.eu','FREE'),
'.mobi' => array('whois.dotmobiregistry.net', 'NOT FOUND'),
'.tv' => array('whois.nic.tv', 'No match for'),
'.in' => array('whois.inregistry.net', 'NOT FOUND'),
'.co.uk' => array('whois.nic.uk','No match'),
'.co.ug' => array('wawa.eahd.or.ug','No entries found'),
'.or.ug' => array('wawa.eahd.or.ug','No entries found'),
'.sg' => array('whois.nic.net.sg','NOMATCH'),
'.com.sg' => array('whois.nic.net.sg','NOMATCH'),
'.per.sg' => array('whois.nic.net.sg','NOMATCH'),
'.org.sg' => array('whois.nic.net.sg','NOMATCH'),
'.com.my' => array('whois.mynic.net.my','does not Exist in database'),
'.net.my' => array('whois.mynic.net.my','does not Exist in database'),
'.org.my' => array('whois.mynic.net.my','does not Exist in database'),
'.edu.my' => array('whois.mynic.net.my','does not Exist in database'),
'.my' => array('whois.mynic.net.my','does not Exist in database'),
'.nl' => array('whois.domain-registry.nl','not a registered domain'),
'.ro' => array('whois.rotld.ro','No entries found for the selected'),
'.com.au' => array('whois.ausregistry.net.au','No data Found'),
'.ca' => array('whois.cira.ca', 'AVAIL'),
'.org.uk' => array('whois.nic.uk','No match'),
'.name' => array('whois.nic.name','No match'),
'.ac.ug' => array('wawa.eahd.or.ug','No entries found'),
'.ne.ug' => array('wawa.eahd.or.ug','No entries found'),
'.sc.ug' => array('wawa.eahd.or.ug','No entries found'),
'.ws' => array('whois.website.ws','No Match'),
'.be' => array('whois.ripe.net','No entries'),
'.com.cn' => array('whois.cnnic.cn','no matching record'),
'.net.cn' => array('whois.cnnic.cn','no matching record'),
'.org.cn' => array('whois.cnnic.cn','no matching record'),
'.no' => array('whois.norid.no','no matches'),
'.se' => array('whois.nic-se.se','No data found'),
'.nu' => array('whois.nic.nu','NO MATCH for'),
'.com.tw' => array('whois.twnic.net','No such Domain Name'),
'.net.tw' => array('whois.twnic.net','No such Domain Name'),
'.org.tw' => array('whois.twnic.net','No such Domain Name'),
'.cc' => array('whois.nic.cc','No match'),
'.nl' => array('whois.domain-registry.nl','is free'),
'.pl' => array('whois.dns.pl','No information about'),
'.pt' => array('whois.dns.pt','No match')
);

public $error;

function available($domain){
$domain = trim($domain);
if (eregi('^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)*[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?$',$domain) != 1){
$error = 'Invalid domain (Letters, numbers and hypens only) ('.$domain.')';
return false;
}
preg_match('@^(http://www\.|http://|www\.)?([^/]+)@i', $domain, $preg_metch_result);
$f_result = '';
$domain = $preg_metch_result[2];
$domain_name_array = explode('.', $domain);
$domain_domain = strtolower(trim($domain_name_array[count($domain_name_array)-1]));
$ext_in_list = false;

if (array_key_exists('.'.$domain_domain, $this->ext)){
$ext_in_list = true;
}

if(strlen($domain) > 0 && $ext_in_list){
$server = '';
$server = $this->ext['.' .$domain_domain][0];
$lookup_result = gethostbyname($server);

if ($lookup_result == $server){
$error = 'Error: Invalid extension - '.$domain_domain.'. / server has outgoing connections blocked to '.$server.'.';
return false;
}

$fs = fsockopen($server, 43,$errno,$errstr,10);

if (!$fs || ($errstr != "")){
$error = 'Error: ('.$server.') '.$errstr.' ('.$errno.')';
return false;
}

fputs($fs, "$domain\r\n");
while( !feof($fs) ) {
$f_result .= fgets($fs,128);
}

fclose($fs);

if($domain_domain == 'org'){
nl2br($f_result);
}

if(eregi($this->ext['.'.$domain_domain][1], $f_result)){
return true;
} else {
return false;
}

} else {
$error = 'Invalid Domain and/or TLD server entry does not exist';
}
return false;
}

}

Using the Domain Availability class

The use of this class is very straight forward. We first initialize a new instance of our WHOIS class, and then pass the domain name through our availability method.

$domain = 'soaptray.com';

$whois = new whois;
$result = $whois->available($domain);

switch($result){
case true: echo 'Domain is available'; break;
case false: echo 'Domain is already registered'; break;
}

There you have it! Let me know if you find a good use for this class in one of your projects! Good luck and happy coding.

Download this class

The working PHP file for this article can be downloaded here.

22 people have left comments

Drew Douglass - Gravatar

Drew Douglass said:

Hi,

“Dugg it!” Just wanted to say thanks for a great tutorial!

Regards,

Drew

Posted on: August 25, 2008 at 7:17 pmQuote this Comment
Regan Johnson - Gravatar

Regan Johnson said:

Drew Douglass said: Hi, Dugg it! Just wanted to say thanks for a great tutorial!

Regards,

Drew

Hey Drew! Thanks for leaving a comment, and I am glad you enjoyed the article.

Posted on: August 25, 2008 at 8:13 pmQuote this Comment
SEO Honolulu - Gravatar

SEO Honolulu said:

Awesome tutorial! Stumbleupon thumbs up all the way :)

Posted on: August 26, 2008 at 10:24 amQuote this Comment
Alejandro U. Alvarez - Gravatar

Alejandro U. Alvarez said:

Thanks a lot for sharing this class, I had been trying to develop something like this for weeks and this is by far a much better approach!

Great work.

Posted on: August 27, 2008 at 3:14 amQuote this Comment
website designs - Gravatar

website designs said:

Not sure if I ll ever use this, but definitely cool.

Posted on: August 27, 2008 at 6:36 pmQuote this Comment
noms de domaine Algerie - Gravatar

noms de domaine Algerie said:

Useful class, I’ll compare it to other scripts, it seems more likely I’ll use this one

Posted on: September 1, 2008 at 4:19 amQuote this Comment
Tech Gringo - Gravatar

Tech Gringo said:

When I first thought about, I assumed it would be difficult, but after looking through your code, I realize just how easy it is using PHP. Thanks a million, I dugg this post and hopefully, I can implement this Domain lookup on one of my own sites soon enough. Thanks again!

Posted on: September 14, 2008 at 6:40 pmQuote this Comment
jeff carter - Gravatar

jeff carter said:

Thanks for the php script. Is it possible to open another socket other than 43 say port 80. Haven’t tried it yet.
Will let you know more later.

Thanks and stumbled.

Posted on: October 9, 2008 at 1:07 amQuote this Comment
James - Gravatar

James said:

greaT JOB

Posted on: October 12, 2008 at 11:57 pmQuote this Comment
jacy - Gravatar

jacy said:

hi, is it possible do it in asp.net??
i m not familiar with php

Posted on: October 17, 2008 at 11:50 amQuote this Comment
Ishak - Gravatar

Ishak said:

Thanks a lot for great tutorial..Cool and easy..
from Malaysia (.my)

Posted on: October 26, 2008 at 1:40 amQuote this Comment
maximo - Gravatar

maximo said:

It’s very beautifull, you are great

Posted on: November 8, 2008 at 9:46 amQuote this Comment
Regan Johnson - Gravatar

Regan Johnson said:

jacy said: hi, is it possible do it in asp.net??
i m not familiar with php

It is possible to do this in other programming languages, however, I am not very familiar with ASP.net. Good luck with the conversion though - start by finding similar functions and you should be able to figure out the other syntax! Same logic.

Posted on: February 14, 2009 at 2:23 pmQuote this Comment
Onabolu Banto - Gravatar

Onabolu Banto said:

Man….I feel you.. The class works like magic. Thanks a lot, I really appreciate it. Av been goin thru’ lots of codes like this but this one is simple and gr8.

Posted on: March 9, 2009 at 5:45 pmQuote this Comment
andrew - Gravatar

andrew said:

WOW thanks a lot for this amazing code. I’ve been looking everywhere for something like this, and this is the only script that comes close to what I need.

Keep up the good work

Posted on: March 18, 2009 at 1:46 pmQuote this Comment
kraazee - Gravatar

kraazee said:

how do i use it on my site. how do i set up.

Posted on: March 22, 2009 at 9:09 amQuote this Comment
matthew - Gravatar

matthew said:

Awesome work in this script. I will be using this for sure on my site. Thanks again for all the hard work.

Posted on: June 3, 2009 at 7:13 pmQuote this Comment
BW - Gravatar

BW said:

I got this set up and working, but i cannot figure out how to echo out the “$error” messages…it simply tells me that an invalid domain name is “unavailable” but not the error (improper TDL, bad characters, etc). Help? Thanks!

Posted on: August 23, 2009 at 11:01 pmQuote this Comment
BW - Gravatar

BW said:

BW said: I got this set up and working, but I cannot figure out how to echo out the

So…I still have this same question and hope someone can help. This is an extremely useful script, but I still cannot figure out how to get the value of the $error variable. Thanks in advance. I am quite sure it must be easy…but nothing I have tried seems to be working.

Posted on: October 4, 2009 at 9:53 pmQuote this Comment
Joseph - Gravatar

Joseph said:

Will it work for all situation?
(i.e. in future, If any new top level domain comes, will it work?)
How to modify according to that?

Posted on: October 8, 2009 at 12:26 amQuote this Comment
Shmuel - Gravatar

Shmuel said:

Hi,

Very nice script in deed, just what I needed.
There is one bug in it though, it wont work with dotted extensions like: .co.il or .co.uk, etc.
I made a small fix on line 95:


$domain_name_array2 = $domain_name_array;
array_shift($domain_name_array2);
$domain_domain2 = implode('.', $domain_name_array2);
$domain_domain = $domain_domain2;

Also I added to entries for to the exts:


'.fi' => array('whois.ficora.fi','Domain not found'),
'.co.il' => array('whois.ripe.net','No data was found to match the request criteria.')

Thanks,

Shmuel

Posted on: October 9, 2009 at 5:16 amQuote this Comment
Khan - Gravatar

Khan said:

Thank you very much for providing this class. Very good logic. I have used it and its working fine.

Thank you again.

Posted on: November 3, 2009 at 11:53 pmQuote this Comment

Leave a Comment-

Comment Guidelines: Basic XHTML is allowed (a href, strong, em, code). All line breaks and paragraphs are automatically generated. Off-topic or inappropriate comments will be edited or deleted. Email addresses will never be published. Keep it PG-13 people!

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>

All fields marked with "*" are required.