Domain Name class

As PHP gets more and more object oriented it becomes interesting to have a nice set of easy-to-use, everyday, really-quite-obvious classes. Today I'm posting three of these: a domain name class, an email class, and a class representing an IP (or IPv4) address.

Using these functions can make your life easier in two ways:

  1. They have static functions allowing you to check if a string is a valid domain name, email address or IPv4.
  2. If you need to pass an email address, domain name or IP address from script to script, or from method to method, it becomes hard to tell where the responsibility for validating it lies.

In a language like PHP, where types aren't very strict to begin with, placing the responsiblity for input validation right is a big issue, since every method using some user given data will have to know it was given right. If you're working within a larger structure it might happen that you have:

Rather than using methods accepting strings that could be empty, null, spam or anything but a valid email address, it makes sense to have the very first method transform the user input into something valid. This way, messages about invalid input can be dealt with straight away, meaning you don't get a long pass down of user error messages. Secondly, all methods down the flow that somehow deal with email addresses can then require their input parameter to be of the type EmailAddress, which saves them the need to check if it actually is an email address.

Very straightforward, but still good to get right

class.DomainName.php

<?php
/*
 * Represents a Domain Name in php
 */
class DomainName
{
    private 
$parts;

    
/*
     * Constructs a new DomainName object from the given string
     */
    
public function __construct($domain$checkTopLevel=true)
    {
        
$parts self::parse($domain$checkTopLevel);
        if (
$parts === false) throw new Exception('Invalid domain name passed to constructor');
        
$this->parts $parts;
    }

    
/*
     * Test wether the givens string is a valid domain name. Returns
     *  false if an invalid domain name is given and an array of parts
     *  if the domain name is valid.
     */
    
public static function parse($domain$checkTopLevel=true)
    {
        if (!
is_string($domain)) return false;
        
        
// Remove final dot. Interestingly, domains officially end with a dot (which
        //  no-one uses) so you can type www.google.com. into your browser and end up
        //  at the right site.
        
if (substr($domain, -1) == '.'$domain substr($domain0strlen($domain)-1);        
        
        
$arr explode("."$domain);
    
        
// Check number of parts in domain
        
if (count($arr) < 2)  return false;
        
        foreach(
$arr as $part) {
            if (!
preg_match("/^(([A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9])|([A-Za-z0-9]+))$/"$part)) {
                return 
false;
            }
        }
        
        if (
$checkTopLevel) {
            
$top $arr[count($arr)-1];
            if (!
self::checkTopLevelDomain($top)) return false;
        }
        
        return 
$arr;
    }

    
/*
     * Check the given TLD against a list of valid ones
     */
    
public static function checkTopLevelDomain($top)
    {
        return 
in_array(strToUpper($top), self::$tops);
    }
    
    
/*
     * Prints the domain to the output
     */
    
public function __toString()
    {
        return 
implode('.'$this->parts);
    }

    
/*
     * Accepted top level domains
     */
    
private static $tops = array(
        
'AD','AE','AERO','AF','AG','AI','AL','AM','AN','AO','AQ','AR','ARPA','AS','ASIA','AT','AU','AW','AX','AZ',
        
'BA','BB','BD','BE','BF','BG','BH','BI','BIZ','BJ','BM','BN','BO','BR','BS','BT','BV','BW','BY','BZ',
        
'CA','CAT','CC','CD','CF','CG','CH','CI','CK','CL','CM','CN','CO','COM','COOP','CR','CU','CV','CX','CY','CZ',
        
'DE','DJ','DK','DM','DO','DZ',
        
'EC','EDU','EE','EG','ER','ES','ET','EU',
        
'FI','FJ','FK','FM','FO','FR',
        
'GA','GB','GD','GE','GF','GG','GH','GI','GL','GM','GN','GOV','GP','GQ','GR','GS','GT','GU','GW','GY',
        
'HK','HM','HN','HR','HT','HU',
        
'ID','IE','IL','IM','IN','INFO','INT','IO','IQ','IR','IS','IT',
        
'JE','JM','JO','JOBS','JP',
        
'KE','KG','KH','KI','KM','KN','KP','KR','KW','KY','KZ',
        
'LA','LB','LC','LI','LK','LR','LS','LT','LU','LV','LY',
        
'MA','MC','MD','ME','MG','MH','MIL','MK','ML','MM','MN','MO','MOBI','MP','MQ','MR','MS','MT','MU','MUSEUM',
        
'MV','MW','MX','MY','MZ',
        
'NA','NAME','NC','NE','NET','NF','NG','NI','NL','NO','NP','NR','NU','NZ',
        
'OM','ORG',
        
'PA','PE','PF','PG','PH','PK','PL','PM','PN','PR','PRO','PS','PT','PW','PY',
        
'QA',
        
'RE','RO','RS','RU','RW',
        
'SA','SB','SC','SD','SE','SG','SH','SI','SJ','SK','SL','SM','SN','SO','SR','ST','SU','SV','SY','SZ',
        
'TC','TD','TEL','TF','TG','TH','TJ','TK','TL','TM','TN','TO','TP','TR','TRAVEL','TT','TV','TW','TZ',
        
'UA','UG','UK','UM','US','UY','UZ',
        
'VA','VC','VE','VG','VI','VN','VU',
        
'WF','WS',
        
'YE','YT','YU',
        
'ZA','ZM','ZW'
    
);
}
?>

Download a full version of this class here: downloads

Jul 9th, 2008

Comments

Michael wrote:

Updated to use preg_match instead of ereg

Apr 12th, 2010

Post your comments here

If you wish to add code to your comment you can use code tags, like this: <code class="php">yourCodeHere</code>.
Quite a large number of languages are supported, although I can't guarantee it'll be pretty. Inside the code tags you can use any characters except for the string "</code>".