Validate an E-Mail Address with PHP, the Right Way

The Internet Engineering Task Force (IETF) document, RFC 3696, “Application
Techniques for Checking and Transformation of Names” by John
Klensin,
gives several valid e-mail addresses that are rejected by many PHP
validation routines. The addresses:
Abc\@def@example.com,
customer/department=shipping@example.com and
!def!xyz%abc@example.com
are all valid. One of the more popular regular expressions found in the
literature rejects all of them:

This regular expression allows only the underscore (_) and hyphen
(-) characters, numbers and lowercase alphabetic characters. Even
assuming a preprocessing step that converts uppercase alphabetic
characters to lowercase, the expression rejects addresses with
valid characters, such as the slash (/), equal sign (=), exclamation
point (!) and percent (%). The expression also requires that the
highest-level domain component has only two or three characters, thus
rejecting valid domains, such as .museum.

Another favorite regular expression solution is the following:

"^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$"

This regular expression rejects all the valid examples in the preceding paragraph.
It does have the grace to allow uppercase alphabetic characters, and
it doesn't make the error of assuming a high-level domain name has only
two or three characters. It allows invalid domain names, such as
example..com.

Listing 1 shows an example from PHP Dev Shed (www.devshed.com/c/a/PHP/Email-Address-Verification-with-PHP/2).
The code contains (at least) three errors. First, it fails to recognize
many valid e-mail address characters, such as percent (%). Second, it
splits the e-mail address into user name and domain parts at the at sign
(@). E-mail addresses that contain a quoted at sign, such as
Abc\@def@example.com will break this code. Third, it fails to check
for host address DNS records. Hosts with a type A DNS entry will accept
e-mail and may not necessarily publish a type MX entry. I'm not
picking on the author at PHP Dev Shed. More than 100 reviewers gave
this a four-out-of-five-star rating.

One of the better solutions comes from Dave Child's
blog at ILoveJackDaniel's (ilovejackdaniels.com), shown in Listing 2
(www.ilovejackdaniels.com/php/email-address-validation). Not only
does Dave love good-old American whiskey, he also did some homework,
read RFC 2822 and recognized the true range of characters valid in an
e-mail user name. About 50 people have commented on this solution
at the site, including a few corrections that have been incorporated
into the original solution. The only major flaw in the code collectively
developed at ILoveJackDaniel's is that it fails to allow for quoted
characters, such as \@, in the user name. It will reject an address
with more than one at sign, so that it does not get tripped up splitting
the user name and domain parts using explode("@",
$email). A subjective
criticism is that the code expends a lot of effort checking the length of
each component of the domain portion—effort better spent simply trying
a domain lookup. Others might appreciate the due diligence paid to
checking
the domain before executing a DNS lookup on the network.