Validating email addresses in PHP with Preg filters, DNS, MX Servers and other checks

There are many tutorials online that show users how to validate an email address, but most do it wrong. This means many websites will reject valid addresses such as customer/department=shipping@example.com or abc!def!xyz%yyy@example.com (yes, they are valid!) with the following expression:

"^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$"

If you’re here through search then you’ve probably already seen a load of these!

The code I’m going to provide:

  1. Allows international domains, and special characters in the email address
  2. Checks for domain existance
  3. Checks for mx records

So…to the code. This was put together from a number of sources, then simply based off an article over at LinuxJournal.

function ValidateEmail($email) {
// Set test to pass
$valid = true;
// Find the last @ in the email
$findats = strrpos($email, "@");
// Check to see if any @'s were found
if (is_bool($findats) && !$findats) {
$valid = false;
}
else {
// Phew, it's still ok, continue...
// Let's split that domain up.
$domain = substr($email, $findats+1);
$local = substr($email, 0, $findats);
// Find the local and domain lengths
$locallength = strlen($local);
$domainlength = strlen($domain);
// Check local (first part)
if ($locallength < 1 || $locallength > 64) {
$valid = false;
}
// Better check the domain too
elseif ($domainlength < 1 || $domainlength > 256) {
$valid = false;
}
// Can't be having dots at the start or end
elseif ($local[0] == '.' || $local[$locallength-1] == '.') {
$valid = false;
}
// Don't want 2 (or more) dots in the email
elseif ((preg_match('/\\.\\./', $local)) || (preg_match('/\\.\\./', $domain))) {
$valid = false;
}
// Make sure the domain has valid chars
elseif (!preg_match('/^[A-Za-z0-9\\-\\.]+$/', $domain)) {
$valid = false;
}
// Make sure the local has valid chars, make sure it's quoted right
elseif (!preg_match('/^(\\\\.|[A-Za-z0-9!#%&`_=\\/$\'*+?^{}|~.-])+$/', str_replace("\\\\","",$local))) {
if (!preg_match('/^"(\\\\"|[^"])+"$/', str_replace("\\\\","",$local))) {
$valid = false;
}
}
// Whoa, made it this far? Check for domain existance!
elseif (!(checkdnsrr($domain,"MX") || checkdnsrr($domain,"A"))) {
$valid = false;
}
}
if ($valid) {
echo $email.' is valid!';
}
else {
echo $email.' is not valid!';
}
}

You’d call this with:

ValidateEmail("test@3cc.org");

Fancy trying it? Click here to demo.

Or if you want this code with all the spaces, click here to view the txt