how to validate domain name in php

how to validate domain name in php  using -'php,regex,domain-name'

Is it possible without using regular expression?

For example, I want to check that a string is a valid domain:


Are valid domains. These are invalid of course:


And so on. So basically it should start with an alphanumeric character, then there may be more alnum characters plus also a hyphen. And it must end with an alnum character, too.

If it's not possible, could you suggest me a regexp pattern to do this?


Why doesn't this work? Am I using preg_match incorrectly?

$domain = '@djkal';
$regexp = '/^[a-zA-Z0-9][a-zA-Z0-9\-\_]+[a-zA-Z0-9]$/';
if (false === preg_match($regexp, $domain)) {
    throw new Exception('Domain invalid');


asked Sep 29, 2015 by mannumits1
0 votes

15 Answers

0 votes

Test cases:

is_valid_domain_name? [a]                       Y
is_valid_domain_name? [0]                       Y
is_valid_domain_name? [a.b]                     Y
is_valid_domain_name? [localhost]               Y
is_valid_domain_name? []              Y
is_valid_domain_name? []       Y
is_valid_domain_name? [xn--fsqu00a.xn--0zwm56d] Y
is_valid_domain_name? [goo]             N
is_valid_domain_name? []             N
is_valid_domain_name? [ ]             N
is_valid_domain_name? []             N
is_valid_domain_name? []             N
is_valid_domain_name? [
answered Sep 29, 2015 by okesh.badhiye
0 votes

With this you will not only be checking if the domain has a valid format, but also if it is active / has an IP address assigned to it.

$domain = "";

if(filter_var(gethostbyname($domain), FILTER_VALIDATE_IP))
    return TRUE;
answered Sep 29, 2015 by sameer rathore
0 votes

I think once you have isolated the domain name, say, using Erklan's idea:

$myUrl = "";
$myParsedURL = parse_url($myUrl);
$myDomainName= $myParsedURL['host'];

you could use :

if( false === filter_var( $myDomainName, FILTER_VALIDATE_URL ) ) {
// failed test


PHP5s Filter functions are for just such a purpose I would have thought.

It does not strictly answer your question as it does not use Regex, I realise.

answered Sep 29, 2015 by param.oncemore
0 votes

Firstly, you should clarify whether you mean:

  1. individual domain name labels
  2. entire domain names (i.e. multiple dot-separate labels)
  3. host names

The reason the distinction is necessary is that a label can technically include any characters, including the NUL, @ and '.' characters. DNS is 8-bit capable and it's perfectly possible to have a zone file containing an entry reading "an\0odd\.l@bel". It's not recommended of course, not least because people would have difficulty telling a dot inside a label from those separating labels, but it is legal.

However, URLs require a host name in them, and those are governed by RFCs 952 and 1123. Valid host names are a subset of domain names. Specifically only letters, digits and hyphen are allowed. Furthermore the first and last characters cannot be a hyphen. RFC 952 didn't permit a number for the first character, but RFC 1123 subsequently relaxed that.


  • a - valid
  • 0 - valid
  • a- - invalid
  • a-b - valid
  • xn--dasdkhfsd - valid (punycode encoding of an IDN)

Off the top of my head I don't think it's possible to invalidate the a- example with a single simple regexp. The best I can come up with to check a single _host_ label is:

if (preg_match('/^[a-z\d][a-z\d-]{0,62}$/i', $label) &&
   !preg_match('/-$/', $label))
    # label is legal within a hostname

To further complicate matters, some domain name entries (typically SRV records) use labels prefixed with an underscore, e.g. These are not host names, but are legal domain names.

answered Sep 29, 2015 by rajeshujade
0 votes

Here is another way without regex.

$myUrl = "";
$myParsedURL = parse_url($myUrl);
$myDomainName= $myParsedURL['host'];
$ipAddress = gethostbyname($myDomainName);
if($ipAddress == $myDomainName)
   echo "There is no url";
   echo "url found";
answered Sep 29, 2015 by gauravsinghal83
0 votes

use checkdnsrr

$domain = "";

checkdnsrr($domain , "A");

//returns true if has a dns A record, false otherwise
answered Sep 29, 2015 by sachin wagh
0 votes

Your regular expression is fine, but you're not using preg_match right. It returns an int (0 or 1), not a boolean. Just write if(!preg_match($regex, $string)) { ... }

answered Sep 29, 2015 by gauravsinghal83
0 votes

Regular expression is the most effective way of checking for a domain validation. If you're dead set on not using a Regular Expression (which IMO is stupid), then you could split each part of a domain:

  • www. / sub-domain
  • domain name
  • .extension

You would then have to check each character in some sort of a loop to see that it matches a valid domain.

Like I said, it's much more effective to use a regular expression.

answered Sep 29, 2015 by sachin wagh
0 votes

If you don't want to use regular expressions, you can try this:

$str = 'domain-name';

if (ctype_alnum(str_replace('-', '', $str)) && $str[0] != '-' && $str[strlen($str) - 1] != '-') {
	echo "Valid domain\n";
} else {
	echo "Invalid domain\n";

but as said regexp are the best tool for this.

answered Sep 29, 2015 by sandeep bhadauria
0 votes

If you want to check whether a particular domain name or ip address exists or not, you can also use checkdnsrr
Here is the doc

answered Sep 29, 2015 by atulpariharmca
0 votes

This is validation of domain name in javascript:

answered Sep 29, 2015 by deepak
0 votes

This post explain how to validate check domain name is valid or not

  • Domain Name Must contain Alpha Numeric
  • Only special character (-) hyphen. is allowed on domain names.
  • Check the generic domain extension (.com, .edu, .gov, .int, .mil, .net, and .org)
  • All International domain extensions (TLDs) approved by ICANN
answered Sep 29, 2015 by bhavin
0 votes

Check the php function checkdnsrr

function validate_email($email){

   $exp = "^[a-z\'0-9]+([._-][a-z\'0-9]+)*@([a-z0-9]+([._-][a-z0-9]+))+$";


        return true;
        return false;


      return false;

answered Sep 29, 2015 by maurya
0 votes

A valid domain is for me something I'm able to register or at least something that looks like I could register it. This is the reason why I like to separate this from "localhost"-names.

And finally I was interested in the main question if avoiding Regex would be faster and this is my result:

    // and localhost- are not allowed
    || $name[0] == '.' || $name[0] == '-' || $name[ $len - 1 ] == '.' || $name[ $len - 1 ] == '-'
    // is the shortest possible domain name and needs one dot
    || ($domain_only && ($len < 4 || strpos($name, '.') === false))
    // several combinations are not allowed
    || strpos($name, '..') !== false
    || strpos($name, '.-') !== false
    || strpos($name, '-.') !== false
    // only letters, numbers, dot and hypen are allowed
    // a little bit slower
    || !ctype_alnum(str_replace(array('-', '.'), '', $name))
    || preg_match('/[^a-z\d.-]/i', $name)
    ) {
        return false;
    // each label may contain up to 63 characters
    $offset = 0;
    while (($pos = strpos($name, '.', $offset)) !== false) {
        if ($pos - $offset > 63) {
            return false;
        $offset = $pos + 1;
    return $name;

Benchmark results compared with velcrow 's function and 10000 iterations (complete results contains many code variants. It was interesting to find the fastest.):

filter_hostname($domain);// $domains: 0.43556308746338 $real_world: 0.33749794960022
is_valid_domain_name($domain);// $domains: 0.81832790374756 $real_world: 0.32248711585999

$real_world did not contain extreme long domain names to produce better results. And now I can answer your question: With the usage of ctype_alnum() it would be possible to realize it without regex, but as preg_match() was faster I would prefer that.

If you don't like the fact that "" is a valid domain name use this function instead that valids against a public tld list. Maybe someone finds the time to combine both.

answered Sep 29, 2015 by sanjaypal1983
0 votes

This is simple. Some php egnine has a problem with split(). This code below will work.

answered Sep 29, 2015 by vijayshukla80