Validating Email Addresses
Validating email addresses is one of those annoying little tasks that long-time PHP developers will need to deal with again and again. Well, maybe. I've spent the last year and a half with only one email checker request, something that makes me very grateful that I get to work on a single large application. However, before my current job I had to deal with this request across multiple frameworks and stacks.
If you're building an application on modern PHP frameworks there's a chance that a pre-build validation engine already exists. Whether it's a package or facade or Standard Validation Zend class, much of this logic has already been built in frameworks. However, if you're building something from scratch or are tweaking things it helps to know how this sort of thing works. So here's a few options for email validation.
Dead Simple Detection
Let's say that you're building a basic application that requires an email address for a login field. You're never going to send email to this address so you don't even care if it is even a valid address, you just need to have some string. There's no need to go overboard with your validation. Some simple detections to make sure it fits the application is all you need.
if (
empty($email_address) ||
strlen($email_address) < 5 ||
strstr($email_address, '@')
) {
exit('Invalid email address!');
}
Regex Pattern Matching
Okay, let's bump things up a notch. You want to make sure that an email address looks valid. There is a standard for this, RFC 5322, and you can construct a regular expression to fit this standard. And so we start down the road of madness.
There are hundreds, if not thousands, of different regex patterns floating around the internet promising to validate email addresses. Most of them do a decent job. Few of them will match every possible address that exists in the real world. There is some decent discussion on this problem on this page: regular-expressions.info email validation.
If you still want to try to use a regular expression for validation, and you're willing to have an imperfect filter, here's a simple option. Just be aware that it could miss some edge cases. Oh, and just because a string looks like an email address doesn't mean it is. I'll explain more later.
if (
preg_match(
'/^[a-z0-9\._%+-]+@[a-z0-9-]+\.[a-z]{2,}$/i',
$email_address
) !== 1
) {
exit('Invalid email address!');
}
PHP Variable Filters
A much more sane solution to validating strings is PHP's filter_var. This function does the same basic thing as regex, a check to make sure that the email address looks like an email address, without worrying about tuning an unwieldy regular expression.
if (
filter_var(
$email_address,
FILTER_VALIDATE_EMAIL
) === false
) {
exit('Invalid email address!');
}
There are still some caveats to this. You are only doing string validation. You are depending on an internal validation process for the string that you can't tweak depending on user feedback. If you're okay with those shortcomings, though, this is a much cleaner solution than using regexes.
SMTP Verification
Up until now all of the options have only been looking at the characters to see if the email address looks legitimate. None of them are actually checking to see if the email has been registered, or if content is deliverable, or if the user is even putting in their address. There are some options to help out with some of this.
Unfortunately, one of the easiest ways to do this has been overused by spammers and is now blocked by most reputable mail services. Whether one tries to send a VRFY or RCPT command to check on an email address these will be ignored. There is still one way to verify by hitting the actual service, though…
Send a Verification Email
Once the user fills out the field, send a verification email to force them to confirm that the string is valid and they own it. It requires a bit more work for the user, and is a multistep process that you'll need to build into the application, but it covers everything. If the string is not a valid format, the email won't send. If the address doesn't exist, the email will fail. And if they don't own the address than they can't confirm.
Combining these methods also make a lot of sense. On initial submit just throw the string at the filter_var function to make sure the string seems legitimate (and maybe have a frontend feedback on the form too, for good luck). Then, if you really want to make sure the email is valid, send a verification. This makes for a much more comprehensive solution than a single, convulated regular expression found from a Google search.
Comments (2)