« Parsing script parameters | Home | E-mail validation in PHP: check IANA TLD »

RFC-(2)822/(2)821 compliant e-mail validation in PHP

This code snippet is probably the most easiliy searched one. However most authors do not read RFC. For example, the following address: "John Doe+Super"@example.com is likely to be valid!

The code snippet below is intended for use primarily with web forms therefore CFWS (comments and folding whitespace) is not allowed.

// returns TRUE if e-mail address is valid, else FALSE
function isEmailRfcCompliant($email) {
    $email = trim($email);
    list($localpart, $domain, $tmp) = split('@', $email);
    if ($tmp) {
        return FALSE;
    }

    $len = strlen($domain);
    if ((1 > $len) || (255 < $len)) {
        // RFC-2821 violation
        return FALSE;
    }

    $len = strlen($localpart);
    if ((1 > $len) || (64 < $len)) {
        // RFC-2821 violation
        return FALSE;
    }

    $quote = strpos($localpart, '"');
    if (0 === $quote) {
        if (strrpos($localpart, '"') !== ($len - 1)) {
            // RFC-2822 violation
            return FALSE;
        }
        if (strrpos($localpart, '\') === ($len - 2)) {
            // RFC-2822 violation
            return FALSE;
        }
        $localpart = substr($localpart, 1, $len - 2);
        $len = strlen($localpart);
        $quoted = TRUE;
    }

    if (0 === strpos($localpart, '.')) {
        // RFC-2822 violation
        return FALSE;
    }
    if (($len - 1) === strrpos($localpart, '
.')) {
        // RFC-2822 violation
        return FALSE;
    }

    if (!$quoted) {
        if (!preg_match('/^[a-zA-Z0-9!#\$\%\&\'\*\+\-\/=\?\^_`{\|}~\.]+$/', $localpart)) {
            // RFC-2822 violation
            return FALSE;
        }
    }

    if (@function_exists('getmxrr')) {
        $arrtmp = array();
        if (getmxrr($domain, $arrtmp)) {
            return TRUE;
        }
    } else {
        // Windoze?
        if (FALSE !== @include_once('Net/DNS.php')) {
            $resolver = new Net_DNS_Resolver();
            if ($resolver->query($domain, 'MX')) {
                return TRUE;
            }
        }
    }

    if (FALSE !== gethostbynamel($domain)) {
        return TRUE;
    }

    return FALSE;
}

Topics: PHP, email, validation | Submitter: iconsultant

3 Responses to “RFC-(2)822/(2)821 compliant e-mail validation in PHP”

  1. E-mail validation in PHP: check IANA TLD at // gotchas.info Says:
    February 2nd, 2006 at 11:52 pm

    [...] Register « RFC-(2)822/(2)821 compliant e-mail validation in PHP [...]

  2. checkthis Says:
    February 2nd, 2006 at 11:52 pm

    Jeffrey Friedl in his book 'Mastering Regular Expression' provides the example of the regular expression for 'RFC-compliant' parsing of the e-mail address.
    This regular expression takes the WHOLE page!

  3. iconsultant Says:
    February 3rd, 2006 at 12:37 am

    I have seen Jeffrey's book. I find his example good for acadmic purposes but not suitable for real-world web forms.

    Some RE features completely useless in web-forms:
    1. 'mailbox' token support
    2. uucp-style routing support
    3. comments and whitespace

    Also unlike the function above, a RE cannot resolve domain names. Non-resolvable domain name is violation of RFC-2821

Comments

You must be logged in to post a comment.

Keep on coding