Its always nice when a site gives you an opportunity to contact the webmaster. You should always make sure, when you are building a website, to give your users opportunity to do this. One way to go about doing this is just giving out your email address. Unfortunately, putting your email address up on your site makes it easy form spam bots to find it and start sending you all sorts of emails. The best way is to make a contact form.
To follow this tutorial, you’ll need the jQuery Library.
Let’s start out web 1.0, with just a simple form with a submit button. You’ll want a simple HTML form that looks like this:
So now that we have a form, we’ll need a PHP page to process that form. What we’ll do is take the message, put it into an email and email it to you (you’ll need to put your email, or whatever email you want to receive contact requests). Put this code into a ‘contact.php’ file:
if (!empty($_POST['contact_text']) && !empty($_POST['contact_email'])) {
$to = 'webmaster@example.com';
$subject = 'Contact Request from '.$_POST['contact_email'];
$message = $_POST['contact_text'];
$headers = 'From: '.$_POST['contact_email']." \r\n" .
'Reply-To: '.$_POST['contact_email']."\r\n" .
'X-Mailer: PHP/' . phpversion();
mail($to, $subject, $message, $headers);
echo "Thanks for contacting me!";
} else {
echo "Please enter your email and a message.";
}
?>
Basically, that code checks to make sure that both $_POST['contact_email'] and $_POST['contact_text'] are defined, and then it constructs an email to you (webmaster@example.com). In the message is the text that they entered. Then it prints a friendly message.
The only problem with what we have so far is that the contact form is very vulnerable to automatic spam. Not quite as bad as putting your email out there, but it is still pretty easy for spammers to just send a request to your ‘contact.php’ page and bombard you with emails. There is a way to prevent this from happening. It involves using PHP’s $_SESSION superglobal to make sure that the contact-er is using your contact form, and not just a single request to contact.php. You need to add a little PHP code to your contact form to make this work. Because we are going to use the session superglobal, we need to set up the session at the top of your pages. In both the page holding the form AND contact.php, put this code at the top:
Now, what we’re going to do is make a random string (an md5 hash of a random number between 1 and 10000), and put it into the form as a ‘hidden’ input field. We also store the hash in a session variable, so we can compare the two in contact.php. Here’s what your form should look like now.
(Notice the PHP lines and the new ‘input’ tag).
And now in contact.php, we need to make sure that the two keys are the same. This is what contact.php should look like:
session_start();
if (isset($_POST['contact_key'])) {
if ($_POST['contact_key'] == $_SESSION['contact_key']) {
if (!empty($_POST['contact_text']) && !empty($_POST['contact_email'])) {
$to = 'webmaster@example.com';
$subject = 'Contact Request from '.$_POST['contact_email'];
$message = $_POST['contact_text'];
$headers = 'From: '.$_POST['contact_email']." \r\n" .
'Reply-To: '.$_POST['contact_email']."\r\n" .
'X-Mailer: PHP/' . phpversion();
mail($to, $subject, $message, $headers);
echo "Thanks for contacting me!";
} else {
echo "Please enter your email and a message.";
}
}
}
?>
Great! Now we have a functioning contact form. The only problem is, when people use the form, they are sent to a boring page with only text in it. So let’s make the form asynchronous with javascript. jQuery javascript, actually. The script will wait for the form submit button to be pushed, and then will use AJAX to send a request to contact.php, thus sending the contact request. When that finishes, it will append the response text to the form to give the contact-er a result (good if all fields were filled in, bad if they forgot their email or a message). All you need to do is put a little bit of code into your page with the form.
contactform = $('form#contact');
contactform.submit(function() {
$.post('/contact.php', $(this).serialize(), function(data) {
$('form#contact').append("
"+data);
});
return false;
});
So there we go. Somebody can, with javascript enabled, just press the send button and send the contact request to your email asynchronously, without your putting your email out to be picked up by spam bots. The best thing about this is that when somebody isn’t running javascript in their browser, they will still be able to use the form effectively.
Obviously you’d want to style up your form and maybe change around the ’submit’ event to make it a little more stylish, but we have here a solid, secure AJAX-PHP contact form which will help make your site more user-friendly and accessible.
UPDATE: If you want to make sure that your form is validated, check out this tutorial.








Chris said:
on July 2, 2009 at 12:14 pm
FYI…this isn’t secure at all. Your form is still easily hijacked as you do no request var validation/filtering. Your concatenated header strings can be easily spoofed and spam messages CC’d and BCC’d with no sweat. Based on how your PHP code operates, comparing session tokens is pretty worthless and isn’t “protecting” much at all. Any spammer can sit there all day long BCCing spam messages right under your nose.
Web Programming 101: Don’t trust user inputs.
Kendall said:
on July 4, 2009 at 1:55 pm
This doesn’t stop many spambots. Most that I’ve seen that visit my site first get the page and can see all the form fields and pick up a session. They then use this session to send a message with all form fields filled out, and they also share the sessions with others so a “valid” sessions gets used multiple times, usually about 4 attempts. What you’ve shown here wouldn’t phase these spambots.
Using a honeypot alone would be more effective. A honeypot being a form field that’s visually hidden (not using the type=”hidden”, but rather CSS) and the PHP script expects to be empty. Spambots will fill it out blindly and thus you’ll know it’s spam. There’s a number of other effective techniques, but the one given in the article does nothing really.
alfred westerveld said:
on July 4, 2009 at 2:08 pm
Good tutorial. Have couple tips for javasript jquery. First of all I think it should be wrapped in $(document).ready(function() {});
Second I would use var contactform = $(’form#contact’); because otherwise global namespace will be polluted.
$(document).ready(function() {
contactform = $(’form#contact’);
contactform.submit(function() {
$.post(’/contact.php’, $(this).serialize(), function(data) {
$(’form#contact’).append(”"+data);
});
return false;
});
});
Tim said:
on July 4, 2009 at 5:39 pm
You should check the POST['contact_key'] with !empty() rather than using isset().
A bot could post an empty contact key and since they didn’t originate for the form, the SESSION['contact_key'] would also be empty.
That would pass the test above and allow the bot to spam your form.
It’s a minor but important change.
Steve Love said:
on July 4, 2009 at 6:35 pm
Nice post. This is a great start to get people thinking about vulnerabilities in their contact forms.
I realize you probably just intended this as a simple example, but for anyone planning to use this code, it should be noted that it’s still wide open for exploits. The main issue is that the random key is not deleted after use. I can simply sit on the form and click the submit button (or write a script to do it) to send successful messages all day long. Or, if I really wanted to, I could visit the form to grab the hidden key and insert it into my own form to spam contact.php. Unset the session variable after validating it and you’ll get a little extra mileage out of this script.
And just as a side note, while we’re talking about giving users an opportunity to contact you, keep in mind that this example will not work for the users who have JavaScript disabled in their browser. In fact, the way this script is written they’ll get no error message at all.
IceGhost said:
on July 5, 2009 at 4:21 am
This is the most unsecure form
There is no input sanitizing/filters nothing
pligg.com said:
on July 5, 2009 at 6:27 am
How to Make a Secure Contact Form with PHP and jQuery…
You should always give your users the opportunity to contact the webmaster, when you are building a website. One way to do it is to give out the email address. Unfortunately, putting your email address up on a website makes it a target for the spam bot…