Building An Email FormHandler
One of the many common tasks for a web developer is to receive data sent from a form, and submit the data to an email address. The code that handles the data, we'll call a "FormHandler", since that is what it does, handle the data coming from the form. This lesson incorporates a number of things we have already learned, and provides some advice for this task.
IMPORTANT: When working on Zephir you can only send email to a seattlecentral.edu address. In previous classes we accidentally sent emails to valid domains like "fake.com" (a producer of cloth plants) and "blah.com" (a South American 'connexion' site) and were therefore blacklisted in South America.
All of our examples on this page use the benign "example.com" which is reserved for use in documentation (try it, and see). However, many of our sample & fake users have different emails, necessitating our adminstrator to possibly lock down email handling from the server. However, the info here is still valid, since you need to move all your files to a permanent server anyway!
Data Sent Via GET/POST briefly available on Server: When we build a form on a website and click submit, the data is returned to the page identified in the action attribute of the form tag. However the data is only available to the page momentarily. If the targeted page is indeed a form handler the data must be immediately processed. The data is not stored by default. As developers we can usually do two things, email the data via the domain's default email server or store the data in a database.
Name Attribute: The "name" attribute on the form indicates how to identify the data we send. As an example, look at the code for asking a user to enter his/her first name in a text box:
Enter First Name:<input type="text" name="FirstName" size="20" maxlength="30" />
The "name" field is identified by the value "FirstName". If the user entered "Frank", we would have what is considered a "name/value pair" of "FirstName=Frank". If you selected the "GET" method to send the data, this is exactly what you would "GET":
formhandler.php?FirstName=Frank
It is best NOT to use the GET method however. Using the "POST" method instead provides a bit more security, handles spaces and special characters in safer manner, and allows the user to input more data, since sending data via the "GET" method and appending the data to the querystring is limited to about 2500 characters. Our form could be targeted at our formhandler page thus:
<form action="formhandler.php" method="post" />
Once we have settled on using the POST method, we can switch to the formhandler page, where we can retrieve the user's input via simple code:
$myFirst = $_POST['FirstName'];
Processing Submitted Data via PHP: If the user had typed "Frank" as in the above example, the variable $myFirst would now contain the string "Frank". This isn't entirely good form (bad pun) since this doesn't screen for bad data, ( a hacker) or no input. A better way to capture that data in the real world would include checking to see if data was submitted in the first place (isset), trimming off any unnecessary spaces (trim), stripping out any illegal characters (strip_tags):
if(isset($_POST['FirstName']){$myFirst = strip_tags(trim($_POST['FirstName']));}
You can go one step further (and avoid unsightly PHP warnings) by equating the $myFirst variable to an empty string, if all else fails:
if(isset($_POST['FirstName']){$myFirst = strip_tags(trim($_POST['FirstName']));}else{$myFirst="";}
While this is one long ugly line of code, it is easily copied and used as necessary in a few seconds. For a review of POST and GET methods and submitting data via forms, please review the Postback1 & Postback2 examples from the POST & GET with Forms lesson.
Newlines, no breaks: The default way to send data via email is text and not HTML. Therefore if we want to process data for the body of a text email you'll be using backslash "\n" on UNIX or "\r\n" on Windows to signify newline instead of the <br /> tag.
Text on Windows Servers: Since carriage returns on windows servers use \r\n instead of UNIX's \n, to protect ourselves from this issue, we'll use a predefined constant that determines the best end of line character for the server involved, PHP_EOL.
Let's assume you are capturing POST data as input by the user thus:
if(isset($_POST['FirstName'])){$myFirst = strip_tags(trim($_POST['FirstName']));}else{$myFirst="";}
This gives us either the user's first name in a variable called $myFirst, or an empty string. You could then add the data from the first name of the user into the body of an email. Let's call the text that will be the body of the email "$myText", in which case you could do something like:
$myText .= "The user has entered his/her first name as: " . $myFirst . PHP_EOL;
Remember the "break" tag (<br />) doesn't apply to straight text on an email! If you gather several variables, and want to display a person's address in a nicely formatted manner on an email, it may look something like this:
$myText .= "The user has entered their name and address as follows:" . PHP_EOL . PHP_EOL; //double newlines
$myText .= $myFirst . " " . $myLast . PHP_EOL";
$myText .= $myAddress . PHP_EOL;
$myText .= $myCity . ", " . $myState . " " . $myZipCode . PHP_EOL;
Emailing via PHP: Once the body text of the email has been built (in our variable called $myText) it is time to get to the business of sending the data. In our case, the email address we are going to send the info to is "hard wired" (non-flexible). We are asking for data from the user, but we know WHO is asking for the data:
mail("me@myemail.com","My Clever Subject Line!",$myText,"noreply@example.com")
The "mail()" function is very simple in PHP. the 4 items required are in order:
- Where to send the email
- What subject line to send
- The entire body of the email
- The address that will show up in the return field
We have already built item 3, the body text. Item 1 is hard wired to the address where we want the email to go. Item 2, the subject line is pre-determined by the fact that we SHOULD know WHAT data we asked the user to give us. For example if we ask a user for his input about how wonderful our website is, we could call our subject:
$mySubject = "My WebSite Feedback"
We could more creative, however, and add date and time info to the subject line, to be more helpful:
$mySubject = "My WebSite Feedback " . date("m/d/y, G:i:s");
Let's go all out, and input the user's name and address in the subject line! This way I can distinguish between multiple form submissions in my email inbox:
$mySubject = "WebSite Feedback From " . $myFirst . " " . $myLast . " " . date("m/d/y, G:i:s");
Now we come to item 4, where the email came from. While we could feasibly request the email address from the user and input it into this spot, it is not adviseable for a couple reasons. Some server's may balk at sending the email at all if the user inputs an invalid email address. If this is the case, you may never be informed, as the initial email would never be sent.
It is safest to "hard wire" an email address associated with the server you are using. Best of all is to set up a "noreply" email address, which is designed to give a visual clue to the reader of the email NOT to try to reply to the sender of the email. After all, this was a form submission!
Now, our eventual email function call could look like:
mail("me@example.com",$mySubject,$myText,"noreply@example.com")
The above example assumes "me@example.com" to be replaced by your actual email, the "noreply@example.com" to be replaced by an email appropriate to your server, and the variables $mySubject and $myText are built prior to the call the function. To see how we this works, here is a word doc that holds a sample email test page named email_test.php.
This file can be used to test email capabilities on your server and to see how a single page postback application can be used to send email.
While testing, remember to change the email address to your email address. Send a simple message first, to be sure the email piece is working. Then add to your subject and body text. Try the form a number of times, and carefully scrutinize how the body text is output.
Adding Data to the Database: You may have been given the task to add the data to a database at the same time as sending the email. This is not difficult, but you need to be careful of a couple of things.
When you are adding data into a database you should use the "addslashes()" or "mysql_real_escape_string()" functions prior to entry to the database. Adding the slashes is necessary to prevent SQL errors on data entry, but add unsightly "slashes" (backward slashes, or "") that are not appropriate for an email.
The easiest way around this is to hit the database with the data AFTER you have built the body of the email ($myText). So, after the $myText is created, re-use the $FirstName variable, and add the slashes:
$myFirst = mysql_real_escape_string($myFirst);
Then you can enter the data into the database as usual:
$insertSQL = "INSERT INTO test_Customers(FirstName) VALUES ('" . $myFirst . "')";
We'll learn to more about adding data to the database in a further lesson.
Client Side JavaScript Validation: When the user enters data in a form if the data is incorrect or if there are required form fields that are empty we can use JavaScript to check our form data before the form submits. If the form data is not entered properly we can stop the submission and pop up a message to the user.
While JavaScript form validation is a required skill for a web developer, we must also process or validate data via PHP on the server as well since JavaScript can be shut off easily. Some developers skip JavaScript validation for this reason.
I recommend using JavaScript validation for most web applications. If the data can be verified on the client side via JavaScript this may result in less work for you to do as a developer, and less work for the server, as well. There are many scripts available to help you "require" input from user on particular form fields. One such link is below:
http://www.tizag.com/javascriptT/javascriptform.php
When you take a JavaScript class you'll learn more about validation. In our example at the bottom of the page JavaScript validation is included to get you started.
Testing A Form: While you are building your form, you may want to test to be sure data is being sent correctly. We can place a bit of PHP code just above the area we process our form data, for example:
While you are testing your form, you could target the form to a test page, for example:
if(isset($_POST))
{
echo '<pre>';
var_dump($_POST);
echo </pre>';
}
die();
In the above we check to be sure data is sent via POST then see what name/value pairs are being delivered and how much data. Check the Troubleshooting page for more help on how to use var_dump().
CAPTCHA & reCAPTCHA: Most websites need a way to allow users to contact the site’s owners. It’s no longer advisable to place an email on a website, as emails can be harvested and their owners become targets for spam.
To avoid the email spam problem we can build a contact form for users to contact our clients. Using a form instead of placing an email on a website is both safer and more convenient.
CAPTCHA is a type of challenge-response test used on web pages to ensure that a form response is not generated by a machine. A typical CAPTCHA requires a user type letters or digits presented via a distorted image.
reCAPTCHA is a free CAPTCHA web service that helps to digitize books, newspapers and old time radio shows. The website owner must download an API file that will contact the reCAPTCHA server that will both serve up the image and provide feedback to ensure a human is entering data in our contact form.
The following is a single page postback application designed to integrate the reCAPTCHA system to prevent form spam. Please download the following ZIP file and read the word document inside it for installation details: reCAPTCHA Email Contact Form
Later we'll learn to add the ability to capture the data submitted in a database table as well. The version above does not yet include database integration.
Third Party Email Applications: For production work where more involved email handling is applicable I recommend researching one of several installable applications or classes that can streamline your work, and allow you to efficiently send HTML based emails as well. Here is one free solution:
PHPMailer
Remember to also go to php.net to view all the official info regarding emailing with PHP!