UPDATE: It is now easier to send a confirmation email to the provided address to validate it, or to use a framework than a custom script.
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/[email protected] or abc!def!xyz%[email protected] (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:
- Allows international domains, and special characters in the email address
- Checks for domain existance
- 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("[email protected]");
Fancy trying it? Click here to demo.
Or if you want this code with all the spaces, click here to view the txt