ITT #15: Create a Simple Contact Form
Reach Out to Visitors with a Simple Contact Form
NOTE: This entry has been improved upon by adding spam protection and sessions. It's strongly recommended that you use the newer version of the simple contact form.
Making yourself accessible is one of the most important aspects of a site that aims to connect with its audience online, and nothing makes a person more accessible than an easy-to-use contact form.
In this week's Instant Tip Tuesday, we'll build a simple (less than 200 lines of code, including comments) contact form that will allow users to contact us without needing to open their mail client or copy and paste our email address into their web mail service. Our finished contact form will do the following:
- Accept the user's name, email, URL, and a message
- Verify that required fields were filled out
- Validate the supplied email address
- Send the user's message to an email address of our choice
- Send the user a confirmation that their message was sent
View the Demo | Download the Files
Step 1 — The Message Form
Our first step is to generate the form so that our user can create their message. As we decided above, we want to accept the user's name, email address, website URL, and a message.
Because we're all savvy with HTML, we won't cover the "why" for the following code. The following is valid XHTML 1.0 Strict:
<h1> Simple Contact Form </h1>
<form action="inc/contact.inc.php" method="post" id="cf">
<fieldset>
<legend>Send a Message</legend>
<label for="cf_n">Name (required)</label>
<input id="cf_n" name="cf_n" type="text" maxlength="75" />
<label for="cf_e">Email (required)</label>
<input id="cf_e" name="cf_e" type="text" maxlength="150" />
<label for="cf_w">Website (optional)</label>
<input id="cf_w" name="cf_w" type="text" maxlength="150" />
<label for="cf_m">Enter Your Message Here</label>
<textarea id="cf_m" name="cf_m" rows="14" cols="45"></textarea>
<input type="submit" name="submit" class="submit" value="Send" />
<input type="submit" name="submit" class="submit" value="Cancel" />
</fieldset>
</form>
We won't go into details on the styling of the form so that we can focus on the processing, but feel free to take a look at the CSS in the demo for a starting point.
Step 2 — Processing the Form
When the user submits the form, it sends the information via the POST method to the file inc/contact.inc.php. Our next step is to write the script that will process the input and send the message.
Validate the Data
Before sending any messages, we need to make sure that the user actually filled out the form and entered valid information. To do this, we first verify that the POST method was used to access the script and that the "Send" button was pressed to submit the form.
After that, we simply check that each form is not empty (and also not equal to the value of the field's label), then store the information in a variable. The email address is special, which we'll talk about in a minute.
<?php
/*
* If the form was submitted and the "Send" button pressed,
* continue processing the data
*/
if($_SERVER['REQUEST_METHOD']=='POST' && $_POST['submit']=='Send')
{
$err = NULL;
// If the name field was filled out, sanitize the input and store it
if(!empty($_POST['cf_n']) && $_POST['cf_n']!='Name (required)')
{
$name = htmlentities($_POST['cf_n'], ENT_QUOTES);
}
else
{
// If the name wasn't entered, create an error message
$err .= "Please enter your name!<br />";
}
// If the email is set, validate and store it
if(!empty($_POST['cf_e']) && $_POST['cf_e']!='Email (required)')
{
// Define a regex pattern to validate the email address
$pattern = "/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/i";
if (preg_match($pattern, $_POST['cf_e']))
{
$email = $_POST['cf_e'];
}
else
{
// If the email doesn't match the pattern, error
$err .= "Please enter a valid email address!<br />";
}
}
// If no email was entered, generate an error message
else
{
$err .= "Please enter a valid email address!<br />";
}
// Check the website field
if(!empty($_POST['cf_w']) && $_POST['cf_w']!='Website (optional)')
{
$site = htmlentities($_POST['cf_w'], ENT_QUOTES);
}
else
{
// Because the website is optional, no error if empty
$site = "none";
}
// Ensure a message was entered, then sanitize it
if(!empty($_POST['cf_m']) && $_POST['cf_m']!='Enter Your Message Here')
{
$message = strip_tags($_POST['cf_m']);
}
// If no message was entered, adds an error message
else
{
$err .= "Please enter a message!<br />";
}
// Process the sanitized and validated data
}
else
{
/*
* If the wrong request method was used or the "Send" button
* wasn't pressed (i.e. "Cancel" was pressed), return the user
* to the contact form with no message.
*/
header("Location: ../");
exit;
}
?>
As noted in the comments above, each submitted field is checked, then sanitized and saved in a variable.
If any of our required fields aren't properly filled out, we store a message in the variable $err. Note that we are appending messages to the variable rather than overwriting the variable. This way, we're able to tell the user every error that occurred, rather than just the last one.
The email check is performed by using a regex pattern, then matching the user input against the pattern using preg_match(). If a match is found, this means the email is valid, so we save it in a variable.
Process the Data
Now that we have our data stored, we're ready to start sending messages. First, we need to ensure that no errors occurred. Since the $err variable is NULL by default, we can check if it's set to catch any errors.
If an error occurred, we simply display the stored error messages and provide a link to try again. (NOTE: In a production environment, it would probably be a good idea to store the input in a session to prevent the user from needing to re-enter their message. This was left out in the interest of keeping this tip short and to-the-point.)
If no errors occurred, we place the supplied information into an email message and fire it off to the designated email address. Then, if the first message sent successfully, we send the user a confirmation email.
All of that functionality is accomplished with this code:
<?php
// Validate and sanitize the input (see above)
/*
* With the data sanitized, we need to check for errors to ensure
* that the message is valid before sending it
*/
if(isset($err))
{
echo '<h1> Oops! </h1>', $err, '<br /><a href="../">Try again!</a>';
exit;
}
/*
* If no errors occurred, send the message
*/
else
{
$to = "Ennui Design <answers@ennuidesign.com>";
$subject = "[Ennui Design] Message from the Ennui Design contact form";
$headers = <<<MESSAGE_HEADER
From: $name <$email>
Content-Type: text/plain
MESSAGE_HEADER;
$msg = <<<MESSAGE_BODY
Name: $name
Email: $email
URL: $site
Message:
$message
--
This message was sent via the contact form on EnnuiDesign.com
MESSAGE_BODY;
if(!mail($to, $subject, $msg, $headers))
{
header("Location: ../?send=error");
exit;
}
// Now send a confirmation email to the user.
$conf_to = "$name <$email>";
$conf_sub = "Thank You for Contacting Us!";
$conf_headers = <<<MESSAGE_HEADER
From: Ennui Design <donotreply@ennuidesign.com>
Content-Type: text/plain
MESSAGE_HEADER;
$conf_message = <<<MESSAGE_BODY
Thank you for contacting us! Your message
was sent successfully, and we will get back
to you as quickly as possible.
All the Best,
Ennui Design
answers@ennuidesign.com
www.EnnuiDesign.com
MESSAGE_BODY;
if(!mail($conf_to, $conf_sub, $conf_message, $conf_headers))
{
header("Location: ../?send=error");
exit;
}
// Send the user back to the main page
header('Location: ../?send=successful');
exit;
}
// Remainder of script (see above)
?>
To send an email with PHP in plain text, all we have to do is put together a "to" address, a subject, the message itself, and the message headers (such as the content type and "from" address). With the message assembled, we simply run the mail() function and check that it fired successfully. If either call fails, we send the user back to the contact form with an error code in the URL to allow for a message to be displayed.
Make It Pretty
To add some client-side form validation, we'll implement the beautiful-forms.js script featured on Ennui Design a few months back. This is done by adding the following to the form HTML:
<script type="text/javascript" src="js/beautiful-forms.js"></script>
<script type="text/javascript">
var formId = "cf";
var reqFields = new Array('cf_n','cf_e','cf_m');
if ( document.getElementById(formId) ) {
prettyForms("cf", reqFields);
}
</script>
For an explanation of how and why this works, read about JavaScript form validation with beautiful-forms.js.
View the Demo | Download the Files
Summary
This contact form is quick and dirty, but it will easily get you up and running with a new point of contact for your users. What do you use to make yourself accessible to users? How would you improve the contact form above? Let me know in the comments!
Comments for This Entry
Hi Jason,
Another great post. Thanks! How well will this hold up against spam? I know little to none when it comes to php, so I have been using a pre-made php script called natemail for dreamweaver for a few years now and it is horrible for getting spam.
1) no anti spam
2) if u made a mistake and return to form - all filled fields are empty again
3) this is lame. nowadays is not very efficient to create such things.
look at the frameworks...
@Anthony:
This won't hold up against spam at all. Adding a really simple anti-spam field wouldn't be too complex, but like nikolai said, there are plenty of existing scripts that exist that will already handle anti-spam for you.
If you find a good one, let me know which one it is!
http://www.visual-blade.com/websites/justcomputers/contactus.php
I'm utilizing this form no that website, truly a great form. I'll adapt it for my own needs and use it to boost my knowledge of PHP and JavaScript.
Post a Comment
Want to show your face? Get a gravatar!