View Full Version : (Non-obvious) Email address validation
d11wtq
08-13-2006, 01:34 PM
Just playing around with email validation and here's a better (although less obvious) regex for email address validation, using (sensible) dot-atom notation for the local part.
<?php
function isValidEmail($string)
{
$dot_atom_re = '[-!#\$%&\'\*\+\/=\?\^_`{}\|~0-9A-Z]+(?:\.[-!#\$%&\'\*\+\/=\?\^_`{}\|~0-9A-Z]+)*';
$implemented_domain_re = '[-0-9A-Z]+(?:\.[-0-9A-Z]+)*';
$full_pattern = '/^'.$dot_atom_re.'(?:@'.$implemented_domain_re.')?$/iD';
if (preg_match($full_pattern, $string)) return true;
else return false;
}
//Addresses marked ** should be INVALID, all others are actually valid
$test_addresses = array(
'foo@bar.com',
'foobar', //local networks
'foo@bar', //local networks
'foo&bar@bar.com',
'foo-bar@bar-com.com.xy.0uy.test',
'g.x.v.y\'test\'@home.tld',
'g£h@foo.com', // **
'bracket[addres]foo@bar.com', // **
'@foo.com', // **
'testy testy@foo.com', // **
'chris=corbyn@bar',
'chris@corbyn=bar', // **
'$$$$****^^%!{}@test.tld' //valid!!!!
);
foreach ($test_addresses as $test)
{
if (isValidEmail($test)) echo $test.' = Valid<br />';
else echo $test.' = Invalid<br />';
}
?>
Prints:
foo@bar.com = Valid
foobar = Valid
foo@bar = Valid
foo&bar@bar.com = Valid
foo-bar@bar-com.com.xy.0uy.test = Valid
g.x.v.y'test'@home.tld = Valid
g£h@foo.com = Invalid
bracket[addres]foo@bar.com = Invalid
@foo.com = Invalid
testy testy@foo.com = Invalid
chris=corbyn@bar = Valid
chris@corbyn=bar = Invalid
$$$$****^^%!{}@test.tld = Valid
There are a lot of email addresses you'd look at and assume are invalid, but are in fact valid. This function can be used for preventing header injection too if the only place you're adding user-defined headers is as an amil address.
Thank you.
Here I'd like to post another email address validation.
This checks the domain name of user email address.
As we know, we get a lot of invalid mail like abc@asdf.com , djfjas@kadfj.com, ttt@xyz.com ...etc.
Those are valid, but not legitimate.
So we can't reply the users or do necessary actions.
The below is the code that check whether domain is valid or not.
<?php
// author : ak
// http://icebergz.flashmo.net
// use ajax method to immediately validate email after user type his/her email
$email = (isset($_REQUEST['em']))?$_REQUEST['em']:exit; // REQUEST either for get or post
$rawurl = explode("@",$email);
$url = "http://".$rawurl[1]; // some domains are valid for both http:// and http://wwww
$url2 = "http://www.".$rawurl[1]; // some are valid only for http://www. [ vice versa]
$valid = true;
$hf = @fopen($url,"rb"); // use @ sign to hide error display
$hf1 = @fopen($url2,"rb");
// if the handle is valid,it'll be something like Resource #id else its string length is zero
if (strlen($hf) == 0){ // if http://somedomain.* is unretrievable,
if (strlen($hf1) == 0) { // then check for http://www.somedomain.*
$valid = false;
}
}
fclose($hf);
fclose($hf1);
if ($valid == false){
echo "Your provided email is invalid. Make it correct!";
}else {
// do mailer and give feedback here
}
exit;
?>
ralph l mayo
08-14-2006, 05:21 PM
Thank you.
Here I'd like to post another email address validation.
This checks the domain name of user email address.
As we know, we get a lot of invalid mail like abc@asdf.com , djfjas@kadfj.com, ttt@xyz.com ...etc.
Those are valid, but not legitimate.
So we can't reply the users or do necessary actions.
The below is the code that check whether domain is valid or not.
<?php
// author : ak
// http://icebergz.flashmo.net
// use ajax method to immediately validate email after user type his/her email
$email = (isset($_REQUEST['em']))?$_REQUEST['em']:exit; // REQUEST either for get or post
$rawurl = explode("@",$email);
$url = "http://".$rawurl[1]; // some domains are valid for both http:// and http://wwww
$url2 = "http://www.".$rawurl[1]; // some are valid only for http://www. [ vice versa]
$valid = true;
$hf = @fopen($url,"rb"); // use @ sign to hide error display
$hf1 = @fopen($url2,"rb");
// if the handle is valid,it'll be something like Resource #id else its string length is zero
if (strlen($hf) == 0){ // if http://somedomain.* is unretrievable,
if (strlen($hf1) == 0) { // then check for http://www.somedomain.*
$valid = false;
}
}
fclose($hf);
fclose($hf1);
if ($valid == false){
echo "Your provided email is invalid. Make it correct!";
}else {
// do mailer and give feedback here
}
exit;
?>
You shouldn't try to check if a host accepts email by testing if it has a listening web server on the default port. You can use gethostbyname($host) != $host to tell if the domain resolves, and beyond that the proper method of validation is to send a challenge email requiring the user to click back through a sent link.
gsnedders
08-14-2006, 05:50 PM
Here's a quick question: do either of them allow IPv6 IPs instead of domains?
marek_mar
08-14-2006, 06:43 PM
Try this: http://ex-parrot.com/~pdw/Mail-RFC822-Address.html
felgall
08-14-2006, 10:38 PM
the proper method of validation is to send a challenge email requiring the user to click back through a sent link.
Most people I know would consider a challenge email to be SPAM since they didn't ask to receive it. Fortunately I now have my spam filter configured so that it automatically deletes all challenge emails before I see them. The ones I used to see were always from people who had sent themselves something from an email form on my web site without following the instructions for making sure that their email program was configured properly to receive it first.
d11wtq
08-14-2006, 10:41 PM
WTF? ~iota are you implying that for a domain name to be valid for email addressing it must run a website? Hmm... no ;)
The best way to check if the email domain is valid is to look up the MX record for the domain. If the domain has no MX record it can't physically work on the internet. Checking users is another matter. Some mail servers give a yes/no when you pass the address as an envelope recipient via RCPT, but many don't (for good reason!). Some servers (barely any) also offer a VRFY command the check the address existence.
WTF? ~iota are you implying that for a domain name to be valid for email addressing it must run a website? Hmm... no ;)
The best way to check if the email domain is valid is to look up the MX record for the domain. If the domain has no MX record it can't physically work on the internet. Checking users is another matter. Some mail servers give a yes/no when you pass the address as an envelope recipient via RCPT, but many don't (for good reason!). Some servers (barely any) also offer a VRFY command the check the address existence.
Thank you so. You're all incredibly smart. :thumbsup:
You mean I must use curl to connect to that domain on port 25 and then try mail commands such as EHLO, VRFY. After getting response OK, I can then assume the email is valid.
Ah yeah, this will take a considerable time as trade-off.:rolleyes:
d11wtq
08-15-2006, 11:36 PM
Thank you so. You're all incredibly smart. :thumbsup:
You mean I must use curl to connect to that domain on port 25 and then try mail commands such as EHLO, VRFY. After getting response OK, I can then assume the email is valid.
Ah yeah, this will take a considerable time as trade-off.:rolleyes:
Even that won't work. Port 25 might not be open on that domain since the MX for it may be handled elsewhere. You need to simply check the MX records for the domain. It's easily done.
d11wtq@w3style:~$ dig MX google.com
; <<>> DiG 9.3.2 <<>> MX google.com
;; global options: printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 44894
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 4, ADDITIONAL: 4
;; QUESTION SECTION:
;google.com. IN MX
;; ANSWER SECTION:
google.com. 3600 IN MX 10 smtp1.google.com.
google.com. 3600 IN MX 10 smtp2.google.com.
google.com. 3600 IN MX 10 smtp3.google.com.
google.com. 3600 IN MX 10 smtp4.google.com.
;; AUTHORITY SECTION:
google.com. 345600 IN NS ns2.google.com.
google.com. 345600 IN NS ns3.google.com.
google.com. 345600 IN NS ns4.google.com.
google.com. 345600 IN NS ns1.google.com.
;; ADDITIONAL SECTION:
smtp1.google.com. 600 IN A 216.239.57.25
smtp2.google.com. 600 IN A 64.233.167.25
smtp3.google.com. 600 IN A 64.233.183.25
smtp4.google.com. 600 IN A 66.102.9.25
;; Query time: 98 msec
;; SERVER: 212.69.37.153#53(212.69.37.153)
;; WHEN: Tue Aug 15 22:35:08 2006
;; MSG SIZE rcvd: 252
d11wtq@w3style:~$
See here, smtp1.google.com is NOT the same server as www.google.com or just google.com. I fear we're drifting off-topic now though. My fault.
vBulletin® v3.8.2, Copyright ©2000-2009, Jelsoft Enterprises Ltd.