Tim's Web Site 2.0

About Me

Miscellaneous

Geek Stuff

Skydiving


My Amazon.com Wish List

Geek Stuff : Tutorials : PHP : Email Form with PHP

Since the Internet is now infested with spammers and scum who would harvest your email address for nefarious purposes it is no longer a good idea to openly display your email address on any of your web pages. Luckily we can get around this inconvenience through the use of a simple HTML form and some PHP code, this way visitors can still contact us without our having to post our email address on the web site. Yay!

Email Form with PHP [Diagram]

Some smarter spammers have seemed to find a way around this though, by automating form submissions. This is the same tool they use to make spam posts to forums, where they sumbit their junk to the page that processes your form. We have a way around this too, to make fairly certain that at least a live human being is at your comments page attempting to send you a message, and not some automated form spam script. Since it is grossly inefficient for a spammer to personally visit every form they wish to submit spam comments to, this prevents most of it. It's a happy thing, read on.

comments.php

We will start by creating a page with our HTML comments form. In this form we will collect the usual stuff like Full Name, Email Address, Subject (like the subject line an email would have), and Comments for the body of their message.

In our <form> tag we will specify the page/script that will process the submitted form data as "thankyou.php", which will also display a Thank You message upon a successful comments form submission.

We will also format the form within an HTML table to make it look nice.

<form name="commentsForm" method="post" action="thankyou.php">
<table border="0">
   <tr>
      <td align="right">Full Name:</td>
      <td><input type="text" name="fullName" size="35" /></td>
   </tr>
   <tr>
      <td align="right">Email Address:</td>
      <td><input type="text" name="emailAddress" size="35" /></td>
   </tr>
   <tr>
      <td align="right">Subject:</td>
      <td><input type="text" name="subject" size="35" /></td>
   </tr>
   <tr>
      <td align="right" valign="top">Comments:</td>
      <td><textarea name="comments" cols="35" rows="4" wrap="physical"></textarea></td>
   </tr>

In an effort to thwart the spammer scum we will add another element to our comments form. We will generate 3 random numbers between 1 and 9 and ask our visitor to add them up. Since most non-imbeciles can add 3 single digit numbers, this should not keep anyone from sending us a message, except maybe Dubya. We will generate our random numbers using the PHP rand() function, so it's pretty easy and will present each visitor with different integer numbers to add.

We will place these 3 random integer numbers in hidden form fields so they're submitted with the rest of the form data to our processing page. I use this method in my own comments form, and so far it has worked pretty well.

   <?php
   // generate 3 random integer numbers between 1 and 9
   $num1 = rand( 1, 9 );
   $num2 = rand( 1, 9 );
   $num3 = rand( 1, 9 );
   ?>
   <input type="hidden" name="num1" value="<?php echo $num1; ?>">
   <input type="hidden" name="num2" value="<?php echo $num2; ?>">
   <input type="hidden" name="num3" value="<?php echo $num3; ?>">
   <tr>
      <td>&nbsp;</td>
      <td>Due to spam form submissions please answer the following simple math problem.</td>
   </tr>
   <tr>
      <td>Please Answer:</td>
      <td><?php echo $num1; ?> + <?php echo $num2; ?> + <?php echo $num3; ?> 
      = <input type="text" name="numAnswer" size="2" /></td>
   </tr>

Then we end our comments form with a submit button that will submit the form values to our "thankyou.php" page for processing, which will email us the message if there were no errors like empty fields or a wrong math problem answer.

   <tr>
      <td>&nbsp;</td>
      <td><input type="submit" value="Send Comments!"></td>
   </tr>
</table></form>

thankyou.php

Error-Check Comments Form Data

We could, if we had no sense, take the submitted form data and fire off an email and hope for the best. Lucky for us, we do have some sense, so we will do some very basic error checking on the form and make sure everything is ok first.

We basically want to make sure the `fullName' field is not blank, the `emailAddress' is a correctly formatted email address (eg: username@domain.com), the `subject' is not blank, and finally that the `comments' field is not blank (if it was blank, what's the point?).

<?php
// create an array to contain any errors we find, and a counter for it
$errorArray = new array();
$errorCounter = 0;

// do some basic error checking of form fields
if( empty($_POST['fullName']) ) {
   $errorArray[$errorCounter] = "Full Name can not be blank";
   $errorCounter++;
}
/* we use a regular expression to make sure it's a properly formatted 
 * email address. we'll get more into regular expressions in another tutorial.
 * for now you can just copy everything between if( and ).
 */
if(!eregi("^[[:alnum:]][a-z0-9_.-]*@[a-z0-9.-]+\.[a-z]{2,4}$", 
 stripslashes(trim($_POST['emailAddress'])))) {
   $errorArray[$errorCounter] = "Email cannot be blank and must be properly formatted.";
   $errorCounter++;
}
if( empty($_POST['subject']) ) {
   $errorArray[$errorCounter] = "Subject can not be blank";
   $errorCounter++;
}
if( empty($_POST['comments']) ) {
   $errorArray[$errorCounter] = "Comments can not be blank";
   $errorCounter++;
}

Next we need to make sure they proved they were a live thinking human and solved our simple math problem. If the answer is wrong, or not there at all, a spammer script (or a complete imbecile) made the post. Either way, if the answer isn't right we don't want to finish processing.

/* make sure `numAnswer' field is not empty (it was at least answered)
 * then make sure that the 3 numbers add up to the answer submitted
 */
if( empty($_POST['numAnswer']) || 
 $_POST['mathAnswer'] != $_POST['num1'] + $_POST['num2'] + $_POST['num3'] ) {
   $errorArray[$errorCounter] = "The answer to the math problem is incorrect.";
   $errorCounter++;
}
?>

If There Were Errors Display Them

If any of the fields were incorrect and caused an error we'll show the error(s) and ask them to click the back button in their web browser, and also provide them a link to return to the form with their existing form data intact.

Since we stored our error message(s) in an array we will determind if there was an error by checking if the number of elements in our $errorArray() is greater then zero using the PHP count() function.

<?php
/* check if there were any errors (if $errorArray has anything in it)
 *
 * if there were errors display the errors and link back to submitting
 * form page, and if no errors proceed with formatting and sending message.
 */
if( count($errorArray) > 0 ) {
   // first display message to visitor that there were errors and provide
   // a link back to the referring form page so they can fix them..
   echo "<p>Your comments form submission contained the following errors. 
    Please click the back button in your browser and go fix them.</p>\n
    <p><a href="javascript:history.go(-1)">click here</a></p>\n";
   
   // then display any errors that occurred
   echo "<ul>\n";
   // if there were errors loop through errors and display
   for( $errorCounter = 0; $errorCounter < count($errorArray); $errorCounter++ ) {
      // we will display each in a bullet point list
      echo "<li>" . $errorArray[$errorCounter] . "</li>\n";
   }
   echo "</ul>\n";
}

Proceed if There were No Errors

If there were no errors we can go ahead with creating and sending the email message.

To start we will add a line at the top of the email message stating who sent the message and the date and time they sent it using the PHP date() function. Then we will go ahead and include the user submitted information, along with their IP address, host and web browser information. Including the IP address and host/browser information is optional, but like to see it.

else {
   // create the email message to send
   $messageBody = $_POST['fullName'] . " sent this message  on " . date("m/d/Y @ h:i a")
      . "\r\r"
      . stripslashes($_POST['fullName']) . "\r"
      . $_POST['emailAddress'] . "\r\r"
      . stripslashes($_POST['comments']) . "\r";
      
      // if browser and user agent info is available include it
      if( !empty($_SERVER['HTTP_USER_AGENT']) ) {
         $messageBody .= "\r" . $_SERVER['HTTP_USER_AGENT'] . "\r";
      }
      
      // show the visitors IP address
      if( !empty($_SERVER['REMOTE_ADDR']) ) {
         $messageBody .= "\r" . "REMOTE_ADDR: " . $_SERVER['REMOTE_ADDR'];
      }
      // also show the form submission method (just in case of spam)
      if( !empty($_SERVER['REQUEST_METHOD']) ) {
         $messageBody .= "\r" . "REQUEST_METHOD: " . $_SERVER['REQUEST_METHOD'];
      }

Now that we have created the body of the email message with the sender's full name, email address, subject, comments, as well as the sender's originating IP address and host/browser information, we will go ahead and send the message using the PHP mail() function.

The \r you see at the end of some lines of code is a carriage return, and the \n is a line break. These are required where they are, so leave them in. You might also notice the \n in some of the PHP code above too, which is optional, but breaks lines so that if you "view source" in your web browser all of the code won't be on one endless line. It makes for easier reading and debugging.

      // send the email message
      $messageSubject = stripslashes($_POST['messageSubject']);
      mail("you@youremail.com", "[Comments Form] {$_POST[subject]}", $messageBody, 
      "From: {$_POST['fullName']} <{$_POST['emailAddress']}>\r\n" 
      . "Reply-To: {$_POST['emailAddress']}\r\n" 
      . "X-Priority: 1\r\n" 
      . "X-Originating-IP: [{$_SERVER['REMOTE_ADDR']}]\r\n" 
      . "X-Mailer: PHP/" . phpversion() . " My Web Site");
}
?>

You should now be able to receive email from your web form! There is no way to eliminate SPAM completely, but the idea is to just make it harder for them to do it. Just like a lock on your door we just want to make it tough enough that they'll just go to the next guy and leave us alone. Hope this helped and it works for you.

©1995 - 2008 Tim Patterson, All Rights Reserved (Unless otherwise noted)