Go Back   CodingForums.com > :: Server side development > PHP

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 01-30-2012, 12:30 AM   PM User | #1
bliland
New to the CF scene

 
Join Date: Jan 2012
Posts: 5
Thanks: 1
Thanked 0 Times in 0 Posts
bliland is an unknown quantity at this point
New to PHP, help with verifying email text field please

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):

Code:
// 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:

Code:
<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

Last edited by bliland; 01-30-2012 at 12:32 AM..
bliland is offline   Reply With Quote
Old 01-30-2012, 12:48 AM   PM User | #2
jmj001
Regular Coder

 
Join Date: Jan 2012
Posts: 271
Thanks: 2
Thanked 65 Times in 65 Posts
jmj001 is an unknown quantity at this point
you could incorporate this function into your script

PHP Code:
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($email0$atIndex);
      
$localLen strlen($local);
      
$domainLen strlen($domain);
      if (
$localLen || $localLen 64) {
         
// local part length exceeded
         
$isValid false;
      }else if (
$domainLen || $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...
jmj001 is offline   Reply With Quote
Old 01-30-2012, 12:59 AM   PM User | #3
bliland
New to the CF scene

 
Join Date: Jan 2012
Posts: 5
Thanks: 1
Thanked 0 Times in 0 Posts
bliland is an unknown quantity at this point
Thank you very much for the quick response jmj001, i'm trying to implement that in the script now, will report back.
bliland is offline   Reply With Quote
Old 01-30-2012, 01:02 AM   PM User | #4
felgall
Master Coder

 
felgall's Avatar
 
Join Date: Sep 2005
Location: Sydney, Australia
Posts: 5,447
Thanks: 0
Thanked 496 Times in 488 Posts
felgall is a jewel in the roughfelgall is a jewel in the roughfelgall is a jewel in the rough
The simplest way to validate an email address in PHP is to use the email filter built into PHP.

Code:
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
    echo "This ($email) email address is considered valid.";
}
__________________
Stephen
Learn Modern JavaScript - http://javascriptexample.net/
Helping others to solve their computer problem at http://www.felgall.com/
felgall is offline   Reply With Quote
Old 01-30-2012, 01:42 AM   PM User | #5
jmj001
Regular Coder

 
Join Date: Jan 2012
Posts: 271
Thanks: 2
Thanked 65 Times in 65 Posts
jmj001 is an unknown quantity at this point
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...

PHP Code:
// 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($email0$atIndex);
        
$localLen strlen($local);
        
$domainLen strlen($domain);
        if (
$localLen || $localLen 64) {
            
// local part length exceeded
            
$isValid false;
        }else if (
$domainLen || $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...
jmj001 is offline   Reply With Quote
Users who have thanked jmj001 for this post:
bliland (01-30-2012)
Old 01-30-2012, 02:16 AM   PM User | #6
bliland
New to the CF scene

 
Join Date: Jan 2012
Posts: 5
Thanks: 1
Thanked 0 Times in 0 Posts
bliland is an unknown quantity at this point
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):

Code:
if (check_is_valid_email($_REQUEST['email'],something)){
any suggestion?
am I doing it totally wrong?
Thanks
bliland is offline   Reply With Quote
Old 01-30-2012, 02:24 AM   PM User | #7
jmj001
Regular Coder

 
Join Date: Jan 2012
Posts: 271
Thanks: 2
Thanked 65 Times in 65 Posts
jmj001 is an unknown quantity at this point
the second argument can be left blank.. set it to false if you want to bypass dnschecking

so you could use it like...

PHP Code:
// 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

PHP Code:
// 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

jmj001 is offline   Reply With Quote
Old 01-30-2012, 02:48 AM   PM User | #8
bliland
New to the CF scene

 
Join Date: Jan 2012
Posts: 5
Thanks: 1
Thanked 0 Times in 0 Posts
bliland is an unknown quantity at this point
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:
Code:
if ($isValid && !(checkdnsrr($domain,"MX") || checkdnsrr($domain,"A"))){
bliland is offline   Reply With Quote
Old 01-30-2012, 02:55 AM   PM User | #9
jmj001
Regular Coder

 
Join Date: Jan 2012
Posts: 271
Thanks: 2
Thanked 65 Times in 65 Posts
jmj001 is an unknown quantity at this point
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...

Last edited by jmj001; 01-30-2012 at 02:59 AM..
jmj001 is offline   Reply With Quote
Old 01-30-2012, 02:59 AM   PM User | #10
bliland
New to the CF scene

 
Join Date: Jan 2012
Posts: 5
Thanks: 1
Thanked 0 Times in 0 Posts
bliland is an unknown quantity at this point
I see, way too much hassle at 4 o'clock in the morning

Thank you very much for the help jmj001!
bliland is offline   Reply With Quote
Old 01-30-2012, 03:03 AM   PM User | #11
jmj001
Regular Coder

 
Join Date: Jan 2012
Posts: 271
Thanks: 2
Thanked 65 Times in 65 Posts
jmj001 is an unknown quantity at this point
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..
jmj001 is offline   Reply With Quote
Reply

Bookmarks

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 04:55 PM.


Advertisement
Log in to turn off these ads.