Jump to content

Email Validation


zimmo

Recommended Posts

I currently have a standard error check on my form for registration. I have read too many conflictions to do with validating the email address to make sure it is valid. Could someone either help me with this, or point me in the right direction to the best way to find out.

 

I need to extend this to validate the email they are inputting.

 

here is the current code

if ( empty($email) ) {
	$error['email_error'] = '<div class="formerror">Please enter your email</div>';
}

 

As you can see its very basic and just checks the field is not empty.

Link to comment
Share on other sites

As conker87 mentions it depends how specific you wish to be. There are many different Regex patterns available but I've never seen one that is fully RFC compliant. There are complete classes written to validate an e-mail address if you wish to be 100% accurate. If you are using PHP 5.2 or newer you could also try something like this...

 

filter_var($email, FILTER_VALIDATE_EMAIL)

 

...but I couldn't swear as to how accurate this is.

Link to comment
Share on other sites

Thanks guys. The problem is like you say the variation of different email addresses, and almost impossible to sort.

 

Lets say that I want to just query a few types, what would be the best way?

 

If anyone knows of any links to help me locate things better, more than welcome.

Link to comment
Share on other sites

I have been playing with the validation and extending what I have got already. I am having problems with it not executing the code I have added, it is not checking the email field for a valid domain. Here is the snippet of code for the error check and my extended with the email check.

 

	if ( empty($email) ) {
	$error['email_error'] = '<div class="formerror">Please enter your email</div>';
	} else {
	function validate_email($email)
		{
		// Create the syntactical validation regular expression
		$regexp = "^([_a-z0-9-]+)(\.[_a-z0-9-]+)*@([a-z0-9-]+)(\.[a-z0-9-]+)*(\.[a-z]{2,4})$";

		// Presume that the email is invalid
		$valid = 0;

		// Validate the syntax
		if (eregi($regexp, $email))
		{
		list($username,$domaintld) = split("@",$email);
		// Validate the domain
		if (getmxrr($domaintld,$mxrecords))
		$valid = 1;
		} else {
		$valid = 0;
		}
		return $valid;
		}
	}

 

Also the query that comes after that. I think this is where I need to add something for the function to validate the email address. I have just included the snippet again.

 

// End of error checking, all fields covered.

if (!$error) {
  $sql = "SELECT * FROM tablea WHERE username = '$_POST[username]' "; 
  $sql_result = mysql_query($sql); 

Link to comment
Share on other sites

Here is a function that I've been using for some time, that was passed along to me by a friend. Seems to work pretty well, and checks DNS MX records too. You're welcome to give it a shot.

 

function validEmail($email)
{
$isValid = true;
$atIndex = strrpos($email, "@");
if (is_bool($atIndex) && !$atIndex)
{
	$isValid = false;
}
else
{
	$domain = substr($email, $atIndex+1);
	$local = substr($email, 0, $atIndex);
	$localLen = strlen($local);
	$domainLen = strlen($domain);
	if ($localLen < 1 || $localLen > 64)
	{
		// local part length exceeded
		$isValid = false;
	}
	else if ($domainLen < 1 || $domainLen > 255)
	{
		// domain part length exceeded
		$isValid = false;
	}
	else if ($local[0] == '.' || $local[$localLen-1] == '.')
	{
		// local part starts or ends with '.'
		$isValid = false;
	}
	else if (preg_match('/\\.\\./', $local))
	{
		// local part has two consecutive dots
		$isValid = false;
	}
	else if (!preg_match('/^[A-Za-z0-9\\-\\.]+$/', $domain))
	{
		// character not valid in domain part
		$isValid = false;
	}
	else if (preg_match('/\\.\\./', $domain))
	{
		// domain part has two consecutive dots
		$isValid = false;
	}
	else if (!preg_match('/^(\\\\.|[A-Za-z0-9!#%&`_=\\/$\'*+?^{}|~.-])+$/', str_replace("\\\\","",$local)))
	{
		// character not valid in local part unless
		// local part is quoted
		if (!preg_match('/^"(\\\\"|[^"])+"$/',
		str_replace("\\\\","",$local)))
		{
			$isValid = false;
		}
	}
	if ($isValid && !(checkdnsrr($domain,"MX") || checkdnsrr($domain,"A")))
	{
		// domain not found in DNS
		$isValid = false;
	}
}
return $isValid;
}

Link to comment
Share on other sites

Do whatever other email field validation you need to do before passing the value to the function, i.e. check the strlen(), make sure the verification field matches, etc.

 

EDIT: I validate the field contains a value, etc. before calling the function, just because the function does use network resources checking the DNS MX records.

Link to comment
Share on other sites

Do whatever other email field validation you need to do before passing the value to the function, i.e. check the strlen(), make sure the verification field matches, etc.

 

EDIT: I validate the field contains a value, etc. before calling the function, just because the function does use network resources checking the DNS MX records.

 

Checking the MX record is sort of useless (and deprecated in today's uses), as it does not actually check the validity of the specific address. I could specify "doesnotexist@foobar.com" and the wildcard record for foobar.com's MXL would return results.

Link to comment
Share on other sites

If you are using PHP 5.2 or newer you could also try something like this...

 

filter_var($email, FILTER_VALIDATE_EMAIL)

 

That is essentially just a regex hiding behind a filter flag; albeit a regex with much more use, testing and breaking than anything that might be cooked up form scratch. 

 

The only way to make sure an email is valid ("valid" meaning someone will receive and hopefully read messages sent to that address) is to send an email (if it bounces, it's probably not valid) and find a way of checking it was received (ask for a click through to your site, perhaps)... but that's hardly a quick and easy nor ideal solution, and isn't without problems of its own.

Link to comment
Share on other sites

Checking the MX record is sort of useless (and deprecated in today's uses)' date=' as it does not actually check the validity of the specific address. I could specify "doesnotexist@foobar.com" and the wildcard record for foobar.com's MXL would return results.[/quote']

 

To an extent, I agree. The one thing it does, however, is make a person realize they will be wasting their time trying to register without at least putting some thought into what fake email address to use. They can't just randomly spit an address into the field; the domain at least has to exist.

Link to comment
Share on other sites

Thanks for all the help. I am going to use the function that was suggestion as seems to do what I want. Now I have not had much dealings with functions, and something I am really trying to understand. So, if someone could show me here, It will not only help BUT learn me how they actually work. I find it so much easier doing it in real world apps, rather than tutorials.. you can grasp it better.

 

So I have my error check end then move on to the insert sql, but I need to check the email is a valid one (or is at least genuine) and then tell me.

 

	if ( empty($email) ) {
	$error['email_error'] = '<div class="formerror">Please enter your email</div>';
	} 	

// End of error checking, all fields covered.

if (!$error) {

function validEmail($email)
{
$isValid = true;
$atIndex = strrpos($email, "@");
if (is_bool($atIndex) && !$atIndex)
{
	$isValid = false;
}
else
{
	$domain = substr($email, $atIndex+1);
	$local = substr($email, 0, $atIndex);
	$localLen = strlen($local);
	$domainLen = strlen($domain);
	if ($localLen < 1 || $localLen > 64)
	{
		// local part length exceeded
		$isValid = false;
	}
	else if ($domainLen < 1 || $domainLen > 255)
	{
		// domain part length exceeded
		$isValid = false;
	}
	else if ($local[0] == '.' || $local[$localLen-1] == '.')
	{
		// local part starts or ends with '.'
		$isValid = false;
	}
	else if (preg_match('/\\.\\./', $local))
	{
		// local part has two consecutive dots
		$isValid = false;
	}
	else if (!preg_match('/^[A-Za-z0-9\\-\\.]+$/', $domain))
	{
		// character not valid in domain part
		$isValid = false;
	}
	else if (preg_match('/\\.\\./', $domain))
	{
		// domain part has two consecutive dots
		$isValid = false;
	}
	else if (!preg_match('/^(\\\\.|[A-Za-z0-9!#%&`_=\\/$\'*+?^{}|~.-])+$/', str_replace("\\\\","",$local)))
	{
		// character not valid in local part unless
		// local part is quoted
		if (!preg_match('/^"(\\\\"|[^"])+"$/',
		str_replace("\\\\","",$local)))
		{
			$isValid = false;
		}
	}
	if ($isValid && !(checkdnsrr($domain,"MX") || checkdnsrr($domain,"A")))
	{
		// domain not found in DNS
		$isValid = false;
	}
}
return $isValid;
} 


  $sql = "SELECT * FROM tablea WHERE username = '$_POST[username]' "; 
  $sql_result = mysql_query($sql); 

  if (mysql_num_rows($sql_result) !=0)

etc.. etc..

 

What I dont understand/trying to learn is after it has executed the function how to I return the value? or how to I get it to work with the form.

 

Here is the form field html extract

 

<p><label for="email">Email</label> <input class="long" type="text" value="<?php echo $email; ?>" name="email" id="email" /><br><?php echo $error['email_error']; ?></p>

 

Appreciate help as learning...

 

 

Link to comment
Share on other sites

Have been reading through several articles now whilst seeing if anyone can help. I am reading that you have to use hidden fields or the like to call the function on FORMS. Is this true? How should I call this function, I am totally stuck as how to get it to work

Link to comment
Share on other sites

You just use it like any other validation method. Make sure the function is included/pasted in the script before it is called. Pseudo code follows . . .

 

if( strlen($_POST['email']) >= 6 ) {
     // field contains minimum no. of chars to be a valid address so send the value to the function
     if( validEmail($_POST['email']) ) {
          // The string is a valid address, and has an active DNS MX record for the domain
     } else {
          //The address is not valid, or has no valid DNS MX record
     }
} else {
     // Address is too short to be valid
}

Link to comment
Share on other sites

Here is a simple three line function I have been improving upon for some time which captures just about every validation of an email format that I can find:

 

function is_email($email) 
{
    $formatTest = '/^[\w!#$%&\'*+\-\/=?^`{|}~]+(\.[\w!#$%&\'*+\-\/=?^`{|}~]+)*@[a-z\d]([a-z\d-]{0,62}[a-z\d])?(\.[a-z\d]([a-z\d-]{0,62}[a-z\d])?)*\.[a-z]{2,6}$/i';
    $lengthTest = '/^(.{1,64})@(.{4,255})$/';
    return (preg_match($formatTest, $email) && preg_match($lengthTest, $email));
}

 

// NOTES:
//
// Format test
// - Username:
//     - Can contain the following characters: 
//         - Uppercase and lowercase English letters (a-z, A-Z) 
//         - Digits 0 to 9 
//         - Characters _ ! # $ % & ' * + - / = ? ^ ` { | } ~ 
//     - May contain '.' (periods), but cannot begin or end with a period
//       and they may not appear in succession (i.e. 2 or more in a row) 
//     - Must be between 1 and 64 characters 
// - Domain:
//     - Can contain the following characters: 'a-z', 'A-Z', '0-9', '-' (hyphen), and '.' (period). 
//     - There may be subdomains, separated by a period (.), but the combined domain may not
//       begin with a period and they not appear in succession (i.e. 2 or more in a row) 
//     - Domain/Subdomain name parts may not begin or end with a hyphen 
//     - Domain/Subdomain name parts must be between 1-64 characters
// - TLD accepts: 'a-z' & 'A-Z'
//
// Note: the domain and tld parts must be between 4 and 256 characters total 
//
// Length test
// - Username: 1 to 64 characters
// - Domain: 4 to 255 character


//=====================================================
// Function: is_email ( string $email )
//
// Description: Finds whether the given string variable
//              is a properly formatted email.
//
// Parameters: $email the string being evaluated
//
// Return Values: Returns TRUE if $email is valid email
//                format, FALSE otherwise.
//=====================================================

 

Note: this does not allow for quoted string format email addresses (which allows pretty much ANY character in the username) but I have never seen one in real life.

 

If anyone can find an error or flaw in this, please let me know.

Link to comment
Share on other sites

Here is the JavaScript version:

 

function validEmail(emailStr)
{
    //Return true/false for valid/invalid email
    formatTest = /^[\w!#$%&\'*+\-\/=?^`{|}~]+(\.[\w!#$%&\'*+\-\/=?^`{|}~]+)*@[a-z\d]([a-z\d-]{0,62}[a-z\d])?(\.[a-z\d]([a-z\d-]{0,62}[a-z\d])?)*\.[a-z]{2,6}$/i
    lengthTest = /^(.{1,64})@(.{4,255})$/
    return (formatTest.test(emailStr) && lengthTest.test(emailStr));
}

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.