Google

Sunday, June 10, 2007

VALIDATE E-MAIL ADDRESS WITH PHP THE RIGHT WAY

Author: Max Teo
Listing 1: Shows an example code that contains 3 errors. First, it fails to recognize many valid e-mail address characters, such as %. Secondly, it splits the e-mail address into username and domain parts at the sign @. E-mail addresses that contain a quoted @ sign, such as koko\@koko@domain.com will break this code. Lastly, it fails to check for host address DNS records.

function validateEmail($email_add) {
if (preg_match(”/^([a-zA-Z0-9])+([a-zA-Z0-9\._-])*@([a-zA-Z0-9_-])+( [a-zA-Z0-9\._-]+)+$/”, $email_add))
{
list ($username, $domain)=split(‘@’,$email_add);
if (!checkdnsrr($domain, ‘MX’)) {
return false;
}
return true;
}
return false;
}

Listing 2: Shows a better way to develop an E-mail validator as it satisfy the following requirements:

-An e-mail address consists of local part and domain seperated by an at sign (@) character (RFC 2822 3.4.1)/
-The local part may consist of alphabet and numeric characters, and the following characters: !#$%&’*+-/=?^_`{|}~, possibly with dot seperators (.), inside, but not at the start, end or next to another dot seperator (RFC 2822 3.2.4)
-The local part may consist of a quoted string - i.e. anything within quotes (”), including spaces (RFC 2822 3.2.5)
-Quoted pairs (such as \@) are valid components of a local part, though an obsolete form from RFC 822 (RFC 2822 4.4)
-The maximum length of a local part is 64 characters (RFC 2821 4.5.3.1)
-A domain consists of labels seperated by dot seperators (RFC 1035 2.3.1)
-Domain labels start with an alphabet character followed by 0 or more alphabet characters, numeric characters or hyphen (-), ending with an alphabetic or numeric character (RFC 1035 2.3.1)
-The maximum length of a label is 63 characters (RFC 1035 2.3.1)
-The maximum lenght of a domain is 255 characters (RFC 2821 4.5.3.1)
-The domain must be fully qualified and resolvable to a type A or type MX DNS address record (RFC 2821 3.6)

function validateEmail($email_add) {
$isValid = true;
$atIndex = strrpos($email_add, “@”);
if (is_bool($atIndex) && !$atIndex) {
$isValid = false;
}
else {
$domain = substr($email_add, $atIndex+1);
$local = substr($email_add, 0, $atIndex);
$localLen = strlen($local);
$domainLen = strlen($domain);
if ($localLen <> 64) {
$isValid = false; // local part lenght exceeded
}
else if ($domainLen <> 255) {
$isValid = false; // domain part lenght exceeded
}
else if ($local[0] == ‘.’ || $local[$localLen-1] == ‘.’) {
$isValid = false; // local part starts or ends with ‘.’
}
else if (preg_match(’/\\.\\./’, $local)) {
$isValid = false; // local part has 2 consecutive dots
}
else if (!preg_match(’/^[A-Za-z0-9\\-\\.]+$/’, $domain)) {
$isValid = false; // character not valid in domain part
}
else if (preg_match(’/\\.\\./’, $domain)) {
$isValid = false; // domain part has 2 consecutive dots
}
else if (!preg_match(’/^(\\\\.|[A-Za-z0-9!#%&`_=\\/$\’*+?^{}|~.-])+$/’ . str_replace(”\\\\”.”",$local))) {
if (!preg_match(’/^”(\\\\”|[^”])+”$/’, $str_replace(”\\\\”,”", $local))) {
$isValid = false; //character not valid in local part unless local part is quoted
}
}
if ($isValid && !(checkdnsrr($domain, “MX”) || checkdnsrr($domain, “A”))) {
$isValid = false; // domain not found in DNS
}
}
return $isValid;
}

No comments: