Secure PHP Contact Form
Wed, 19 March, 2008 – 12:05 pm
I've written up an easy to use, secure, accessible and XHTML Strict compliant contact form, originally for someone to use on their site, but figured I'd post it up here as a bit of a PHP tutorial for anyone who wants to understand what's going on, or for others to just download, follow the instructions and use. I'll explain its usage today and then dissect the form for any PHP learners later in the week.
First off, download the contact form, unzip it and open it in your favourite coding editor. The best version of this form requires PHP 4.4+ however I've altered the line that depends on this version so that you can use it down to version 4.0 however foreign characters will not be checked in the name. Both are contained in the download file.
This won't work straight out of the box. You'll need to edit a few lines first plus add in your surrounding HTML markup.
Edit the Basics
To get this up and running with minimal effort you need to do the following (from top down in the file).
- Edit the $to_email variable to contain your email address. So replace 'you@yourdomain.com' with your own email address, ensuring the double quotes are still kept around the email address.
- Edit the $redirect variable to contain the address, relative to the root, of your thank you page. So if your thank you page is found at http://www.yourdomain.com/contact/thankyou.html this value will become "contact/thankyou.html".
- Edit the $subject variable to contain the text you want to appear in your email subject when you receive an email from the form.
- Locate the line >!– Your Header HTML code or include goes here –< and replace it with your standard site header markup. This could be a PHP include to include the header file, or plain HTML markup.
- Locate the line >!– Your footer HTML code or include goes here –< and replace it with your standard site footer markup. Again, this can be a PHP include or the plain HTML markup.
This should then leave you with a file that has the following sections:
- PHP Script
- HTML Header markup
- Form in the content area
- HTML Footer markup
At this point you should be able to upload this file to any PHP enabled server, view the file, complete the form and submit it. An email should then come through to your specified email account.
Advanced Options
There's two advanced options in this form. The first is to add additional fields into the form, and they'll still be picked up in the email. To do this, edit the form to include your additional form fields (checkboxes and file uploads are not supported in this form) using the following method (if you're not sure on working with forms, read up on accessible form layouts):
- Form Code Excerpt
-
- <div>
- <label for="cftext">Title: </label>
- <input type="text" name="cftext" id="cftext" size="30" value="<?php get_value('cftext') ?>" />
- </div>
Where text makes up your input's fieldname. I would recommend keeping 'cf' at the start of all of your fieldnames as this means there is less potential for variables to clash in the PHP and it can help to reduce spam as spammers will often assume your field names are the general ones of 'name', 'email', message' etc. Title is then the value displayed on the page, so the form label.
The second advanced option is to also control your required fields. Near the top of the script there is a line:
- PHP Code Excerpt
-
- // Specify the required fields
- $req_fields = array("cfname", "cfemail", "cfmessage");
This array lists the fields that are required to contain content. So if you added 3 extra fields, eg. cfurl, cftelephone and cfaddress and you want to make the telephone and address field required, but not the url field, then you can add these in by adding them to the end of the comma delimited list i.e.
- PHP Code Excerpt
-
- $req_fields = array("cfname", "cfemail", "cfmessage", "cftelephone", "cfaddress");
This will then check that both the telephone and address fields have content in them, however the URL field can be left blank. Of course it will be wise to add
- HTML Code Excerpt
-
- <em>Required</em>
After the label title and before the closing label tag, as I've done with the other required fields.
Guarantees
There are none! The form is secure to the best of my abilities. It checks against email header injection, it removes all html tags that may have been entered into the form, it checks the name entered contains just typical characters that a name would contain (including foreign characters)*, it checks your required fields contain content and it will email all details plus the user's given IP address and browser details through to your specified email address. By using less than general field names, spam should be reduced to human spam (I use this method elsewhere and rarely get any spam off my forms that's not human generated).
The form is accessible in that when you click a label title the cursor will be placed in the input box or textarea. It uses the correct markup of a fieldset and legends, and if you choose to extend the form I recommend you continue with these standards. Suggested CSS for the styling of a form and error warning is below.
- Suggested CSS Code
-
- ul.warning {
- color: #c00;
- font-weight: bold;
- }
- fieldset {
- width: 500px;
- border:none;
- border-top: 1px solid #999;
- padding: 10px;
- margin-top: 10px;
- }
- legend {
- font-weight: bold;
- padding: 0 5px;
- }
- label {
- width: 125px;
- float: left;
- text-align: right;
- margin-right: 5px;
- }
- form div {
- clear: both;
- margin-bottom: 10px;
- }
So give it a go and let me know what you think. Any problems or comments, post them below and I'll do my best to help out or accommodate you
* Only in the PHP 4.4+ version.


3 Responses to “Secure PHP Contact Form”
Hello Sarah,
Though basically a nice solution, there are some problems with the PHP 4.4+ version of the contact form as it stands. (I have not checked the other version.)
1) The most serious of these actually prevents the form from working at all. The statement on line 74 should be if(empty($error_msg) — NOT if(!empty($error_msg). The line at present means the email will be built only if errors are present!
2) Non-empty but visually blank fields, i.e., containing one or more spaces, are not trapped. This is easily fixed by trimming $value in the block of code starting at line 43.
I hope these observations are helpful.
By normanw on Mar 23, 2008
Hey Norman, thanks for your pointers. I must have stared at that code so much I started going cross eyed and didn't spot the additional exclamation mark in the if statement. I'd tested it then typically altered something and didn't think to retest. I knew I should have got a fresh set of eyes on it!
I've altered the required fields check too to include the trim. Not sure why I missed that out, that was another addition, trying to make it as easy for non PHP users as possible.
Thanks again, much appreciated
By Sarah on Mar 23, 2008