...

View Full Version : New to PHP, help with verifying email text field please



bliland
01-30-2012, 12:30 AM
Hi everyone, I'm having problems with a free contact form script I found online.
I have some knowledge about code in general, however I'm new to PHP and after a few hours trying to solve the issue I decided to post here asking for help.

The contact script works fine, however it doesn't seem to detect when the e-mail field is left blank and sends the e-mail anyways.
It also sends the e-mail if the e-mail filed is clearly fake (a.k.a. a@b.com), though I'm not sure weather there is a quick fix for that, so the main issue here is fixing the code so to have it return an error if the e-mail field is left blank.

the section of the script about validating the email field (should the script be needed in full please ask and I'll provide it, I just thought I'd keep it short):



// Validate email field.
if(isset($_REQUEST['email']) && !empty($_REQUEST['email']))
{
if(preg_match("/(%0A|%0D|\n+|\r+|:)/i",$_REQUEST['email'])){$errors[] = "Email address may not contain a new line or a colon";}
$_REQUEST['email'] = trim($_REQUEST['email']);
if(substr_count($_REQUEST['email'],"@") != 1 || stristr($_REQUEST['email']," ")){$errors[] = "Email address is invalid";}
else{$exploded_email = explode("@",$_REQUEST['email']);
if(empty($exploded_email[0]) || strlen($exploded_email[0]) > 64 || empty($exploded_email[1])){$errors[] = "Email address is invalid";}
else{if(substr_count($exploded_email[1],".") == 0){$errors[] = "Email address is invalid";}else{$exploded_domain = explode(".",$exploded_email[1]);
if(in_array("",$exploded_domain)){$errors[] = "Email address is invalid";}
else{foreach($exploded_domain as $value){if(strlen($value) > 63 || !preg_match('/^[a-z0-9-]+$/i',$value)){$errors[] = "Email address is invalid"; break;}}}}}}
}


Adittionally, here's the code on the actual page displaying the contact form:


<form id="form1" name="ContactForm" method="post" action="FormtoEmail.php">
<p>
<label>
Name:<input name="name" type="text" id="name" />
</label>
<label><br />
Email:<input name="email" type="text" id="email" />
</label>
<label><br />
Comments:<br /><textarea name="comments" cols="50" rows="10" id="comments"></textarea></label><br /><br />
<input type="Submit"/>
</p>
</form>

Additional notes: The form returns an error if the email field contains more than one '@', or if the @ is missing

Thank you very much for the help

jmj001
01-30-2012, 12:48 AM
you could incorporate this function into your script


function check_valid_email($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;
}

it's a fairly exhaustive check that also does a dns lookup to check it's on a valid domain...

bliland
01-30-2012, 12:59 AM
Thank you very much for the quick response jmj001, i'm trying to implement that in the script now, will report back.

felgall
01-30-2012, 01:02 AM
The simplest way to validate an email address in PHP is to use the email filter built into PHP.


if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
echo "This ($email) email address is considered valid.";
}

jmj001
01-30-2012, 01:42 AM
hmm.. not sure I agree with felgall.. but hey we are all allowed opinions right? ;)

I tried to test the filter_var option just now alongside the email verification function I listed earlier, on my local machine against a couple thousand email addresses I have and straight away got the error:

Fatal error: Call to undefined function filter_var() in xxxx

It seems php has to be compiled with specific PECL extension to use filter_var so straight away that makes it harder for me to use anyway...

Anyway, I tidied up the verification function and added an option to bypass the dns checking...


// Validate an email address with dns lookup
function check_is_valid_email($email,$chkdns=true){
$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($chkdns){
if ($isValid && !(checkdnsrr($domain,"MX") || checkdnsrr($domain,"A"))){
// domain not found in DNS
$isValid = false;
}
}
}
return $isValid;
}

when tested on 2000 email addresses in my db it showed no false positives, it picked out only invalid email addresses... works for me

btw: I got this function from this site: http://www.linuxjournal.com/article/9585?page=0,3
and tweaked it a tiny bit to suit me...

bliland
01-30-2012, 02:16 AM
thanks fellgal, I'll give a go to that one too should I fail miserably at implementing jmj001's suggestion :)

jmj001, i'm trying to figure out the implementation of the function you suggested and I have one question (baring in mind I speak using my C++ knowledge, so I might be talking rubbish...).

So I've added your function to my php, now I need to make a call to it feeding in the parameters to allow the check to happen, problem I have is:
what should I feed as second variable while calling the function?

This is how my call looks now, as you can see I don't have a second parameter to feed to it (not even sure that the one I fed as first parameter would actually feed it the content of the field "email" from the form in all honesty):


if (check_is_valid_email($_REQUEST['email'],something)){

any suggestion?
am I doing it totally wrong?
Thanks

jmj001
01-30-2012, 02:24 AM
the second argument can be left blank.. set it to false if you want to bypass dnschecking

so you could use it like...



// WITHOUT dns checking
if(check_is_valid_email($_REQUEST['email'],false)){
// do whatever you do for a valid email here
}else{
// do what you do for a failed email here
}



// WITH dns checking
if(check_is_valid_email($_REQUEST['email'])){
// do whatever you do for a valid email here
}else{
// do what you do for a failed email here
}

bliland
01-30-2012, 02:48 AM
That's working! Thanks man!

however, if I try to enable the dns check, once i submit the form it tells me:

Call to undefined function checkdnsrr()

which makes sense really since I noticed I got no function definition for it but the code does call to it towards the end:


if ($isValid && !(checkdnsrr($domain,"MX") || checkdnsrr($domain,"A"))){

jmj001
01-30-2012, 02:55 AM
yeh.. it seems checkdnsrr is not available on a windows server but it should be included in a linux distro, if it's not on your server you could just leave the dnscheck as false..

checkdnsrr is a built in php library function but it needs to be compiled in with php to work...

bliland
01-30-2012, 02:59 AM
I see, way too much hassle at 4 o'clock in the morning :)

Thank you very much for the help jmj001!

jmj001
01-30-2012, 03:03 AM
no probs.. actually i think you may have read my last post before i edited it.. it seems checkdnsrr is not available on a windows server and i'm guessing you're running this on a windows machine..

anyway, cheers.. :thumbsup:



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum