Validating a domain string in PHP


It is not uncommon to need to validate a string passed to a PHP script which purports to be a domain name, or URL. In a past project, I had to validate a domain but without the scheme. This turned out to be much harder that I thought, as the PHP validate filter could only specify that a scheme was required or optional, not absent.
Additionally, parse_url() had a bug which broke validation (since fixed in PHP 5.4.7):

// returns true before PHP 5.4.7!
parse_url('http://.com', PHP_URL_HOST);

I searched on the internet for hours, but every solution I could find failed to work properly – some even failing their own stated tests.

In the end, I built one myself and made sure it passed all the tests. If you are running a PHP version earlier than 5.4.7 and want to validate domains without their scheme then feel free to use it. Let me know how you get on in the comments, or if you come across any issues. I’ve also made a little page showing the domain validation tests.
No credit necessary, but please don’t claim it for yourself. Let me know if you have any issues (or even better, suggest fixes!).

function is_domain($domain) {
    $domainlen = strlen($domain);
    if ($domainlen < 4 || > $domainlen 255) {return false;}
    /*
    see https://david.lidstone.me/domain_test.php for test cases.
    ^[a-z0-9] From start of string (denoted by the ^), must start with alpha numeric
    ( = start a sub pattern which contains...
       \\.(?![\\.|\\-]) = period not followed by another period or hyphen
       | = OR [a-z0-9] = any alpha-numeric
       | = OR [\\.(?![\\.|\\-]) = hyphen not followed by another hyphen or period
   )* = close sub pattern - can be matched any number of times
   \\.[a-z0-9]{2,}$ = must end with (denoted by the $) a period and at least 2 alpha numerics
   i = case insensitive regex
   */
   $regex = '/^[a-z0-9](\\.(?![\\.|\\-])|[a-z0-9]|\\-(?![\\-|\\.]))*\\.[a-z0-9]{2,}$/i';
   if (!preg_match($regex, $domain)) {
      return false;
   }
   return true;
}

Leave a Reply

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