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.


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 Sun, 23 March, 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 Sun, 23 March, 2008
This is the best script I have found for ease of use, but as a php newbie I have found one aspect of the script really frustrating.
That aspect is the fact that the submit button returns a value in the emailed form.
How to stop this? It's a minor problem I know, but I would love to get rid of the submit: Submit value at the end of the email.
By Steven W on Mon, 15 September, 2008
Hi Steven, I'll amend the file to remove the submit info. Give me 24 hours
By Sarah on Mon, 15 September, 2008
This is so nice, clean and simple to implement, thanks.
I needed a quick contact form for an upcoming friends site, and this looks the business. I was thinking of adding captcha, but then you have the problems with accessibility.
Thanks for sharing!
By Ryan on Mon, 10 November, 2008
You're welcome Ryan
By Sarah on Mon, 10 November, 2008
Hi
I'm trying to implement a form in the autopull page.
I tried with yours but I just can't make it work.
How do I know if I can use php in the site?
Because maybe that is the reason why the form does not work…
Also the css, do I have to add it to the same file or can I use the same external sheet I use for the rest of the site (if so… where do I link it?)
I have no idea of php, but I need to place a form and plain html will get me tons of spam :/
By nimraithkar on Wed, 26 November, 2008
To check if you can use PHP, create a simple PHP page eg. a blank file with
<?php echo "Hello World" ?>in it and save it as hello.php. Upload this to your site and go to it. If you see 'Hello World' then it's worked. If you see all the code, then it hasn't.
The CSS code would go in an existing stylesheet, or a new one. You'd link to it via the header of the page.
But check on whether you can run PHP first. If you can't, contact your host and see if they can allow it for you as you're on Apache, so the server should be capable of running it
By Sarah on Wed, 26 November, 2008
I uploaded the hello.php file and the browser (FF) tries to open or save the file…
but lately when I try to open a php file directly in the browser without uploading, it makes the same.
But I used to open them like that and visualize the page and with the code in it.
Anyway. If I can't see the php as I should then I will better contact the host as you say.
Thanks a lot. I'll keep your code and try to use it latter.
By nimraithkar on Wed, 26 November, 2008
Hi there – I'd sure like to use an image for the submit button. Am a PHP newby so am not quite sure how to do this. Any idea? Thanks.
By Karen on Fri, 28 November, 2008
Hi Karen,
To use an image you'll need to change the submit button to be of type image (see http://htmldog.com/reference/htmltags/input/ for how to do this).
Then you'll need to change the line of PHP code that's currently
if (isset($_POST['cfsubmit']) && trim($_POST['cfsubmit']) != "") :to check for cfsubmit_x as an image input sends co-ordinates i.e.
if (isset($_POST['cfsubmit_x']) && trim($_POST['cfsubmit_x']) != "") :Hope that helps. Let me know if you have any problems or questions with it
By Sarah on Sun, 30 November, 2008
Hi Sarah,
Great little script..just what I was after!
I've edited the actual form and styled it all as I want but the 'thank you' page doesn't seem to work for me
I'm using: $redirect = "thankyou.php";
The file is in the dir and when I submit the email gets generated and arrives but the browser doesn't direct to the thank you page. Tried in both IE & FF.
Any ideas?
By awzm on Fri, 5 December, 2008
Hi awzm. What happens when you submit the page. Does it display the form again or go to a blank page? What's the URL in the browser? If it has your thankyou.php file in the URL, is the URL correct, if not then you'll need to fix that. Otherwise, the other problem could be that you've managed to insert a space at the very top of the file, which would stop the redirect from working.
However check the URL. If it's still the form's URL then the redirect isn't running so you need to check for white space or any output above the PHP, if it contains the thankyou.php in the URL, then you need to check that the path is correct.
By Sarah on Sat, 6 December, 2008
Very cool Sarah, thank you. Happy holidays…
By Ned Eldredge on Fri, 12 December, 2008
Thanks ever so much!!!!!
By eddie on Wed, 17 December, 2008
Hey Sarah–
Thanks for the great script. I'm new to PHP and this is a great help.
I just set this up and change the variables as necessary. I went to test it, and upon submission, I got an error saying that my name appears to be invalid. I just typed it in as Valerie Wininger. Any idea why this might happen? Thanks!
By Valerie Wininger on Wed, 11 February, 2009
Hi Valerie. What version of PHP are you running? You can check this by creating a file on your server with <?php phpinfo() ?> in it and going to it in your browser.
By Sarah on Thu, 12 February, 2009
Hello again–The server is running PHP 5.2.1.
Thanks!
Valerie
By Valerie Wininger on Thu, 12 February, 2009
Hi Valerie,
Although it shouldn't be a problem, the only thing I can think of is that the 4.4+ version is causing the problem. Have you tried the 4.0+ version instead?
By Sarah on Sat, 14 February, 2009
Very nice tutorial. It's nice to see someone that actually explains along the way rather than just saying 'change this to this' without an explanation.
I went to the link for Style:Phreak's form as you suggest and looked at the form there. Is your script easy to implement for that form? And, how difficult is it to incorporate 'captcha'?
John
By John on Sat, 21 February, 2009
You specify that file uploads cannot be used. What changes would be necessary to allow them?
Thanks for a great script!
Steve
By Steve on Sun, 22 February, 2009
@John you could implement the Style:Phreak form yes. This script can easily be used as a starting point for any contact form if you understand the basics of PHP form processing. Again, a captcha can be integrated easily, however with all the checks in the form it's unlikely you would need one.
@Steve You would need to add the enctype attribute to the form, add a file input box into the form and then upload it by accessing the $_FILE superglobal. Your best option is to have a look at the PHP function move_uploaded_file() as you'll probably find some code examples for that which will explain everything you need
By Sarah on Wed, 25 February, 2009
I'm in the process of rebuilding our site and have installed your form. It works great with no thank you page (other than a page not found error), but when I added a thank you page, I'm getting a nasty error that tells me I've messed up. Both the contact form page and the thank you page are in the same directory. This is the error:
Warning: Cannot modify header information – headers already sent by (output started at D:\WWW\caravanbeads.net\wwwroot\test_site\pages\contact.php:9) in D:\WWW\caravanbeads.net\wwwroot\test_site\pages\contact.php on line 143
Help greatly appreciated!
bk
By Barry on Sun, 29 March, 2009
I should add that the forms are being submitted correctly; just the thank you page part is broken.
The form submission I just noticed still includes this: cfsubmit: Submit
as the last line.
Thanks,
bk
By Barry on Sun, 29 March, 2009
Hi Barry,
The first error is due to output being on the page before the redirection comes in, so you'll need to check that you've not inserted any characters, including spaces, at the top of the file before the opening php tag.
For the second issue, the submit is there because the submit button is clicked. You can stop this from coming through by going to line 78 in the code (or 78 in the original file), finding
foreach ($formstuff AS $key => $value) :$message .= $key.": ".$value."\n\n";
endforeach;
and changing it to
foreach ($formstuff AS $key => $value) :if ($key != "cfsubmit") :
$message .= $key.": ".$value."\n\n";
endif;
endforeach;
By Sarah on Sun, 29 March, 2009
Hi Sarah,
Great script, and I have got the form to work (mostly!) using the PHP 4.0 version.
If I input info into a text field and then miss another in a required field and then click submit – I get the warning message okay, but in the text field that I have input info into instead of the text I get the following error message (without the quotes):-
"Notice: Undefined variable: form_value in E:\domains\l\limousinlakes.co.uk\user\htdocs\contact\contact-form.php on line 113 "
Any idea what is going wrong here?
Many thanks for the script.
Chris
By Chris on Mon, 6 April, 2009
Hi Chris, looks like I missed a bit in the get_value function. If you look at the end of the PHP code around line 110 (ish) you should see
function get_value ($formvalue) {if (!empty($_POST[$formvalue])) :
if (get_magic_quotes_gpc()) :
$form_value = stripslashes($_POST[$formvalue]);
endif;
echo $form_value;
endif;
}
change this to be
function get_value ($formvalue) {if (!empty($_POST[$formvalue])) :
if (get_magic_quotes_gpc()) :
$form_value = stripslashes($_POST[$formvalue]);
else :
$form_value = $_POST[$formvalue];
endif;
echo $form_value;
endif;
}
That should fix the problem. Cheers for letting me know.
By Sarah on Mon, 6 April, 2009
Great easy script for non-PHP expert. Only question I have is how can I remove the (aproximately) 1 px border that surrounds the form? Your time and efforts are greatly appreciated!
By Renee on Wed, 15 April, 2009
Okay, just figured out how to rid the border. One more favor? How can I move the Submit button to be centered under the TextArea? Right now it's way over to the left…I'm afraid no one will notice it.
By Renee on Wed, 15 April, 2009
To remove the fieldset border just use
#contactformid fieldset { border: none }To move the submit button, target the submit button and give it a left margin eg.
#cfsubmit { margin-left: 20px }By Sarah on Wed, 15 April, 2009
great script! for some reason when I input an invalid email address, the fields don't stay filled in, though I assume they should with the get_value function.
could it be that my site is on php 5?
By keight on Sun, 26 April, 2009
Hi keight, have you got the latest version of the script and did you check the comment a few above as I'd missed an else statement out of the get_value function. I think I've updated the download script but I'll check in the morning
By Sarah on Tue, 28 April, 2009
That was it! I checked my code after seeing that comment, but guess I didn't compare closely enough. Thanks!
By keight Bergmann on Tue, 28 April, 2009
Awesome form, and easily implemented for a PHP newbie. Thank you very much!
By Chris on Wed, 27 May, 2009
Any reason you can think of that the form would redirect properly on my localhost running php 5.2.8, but not redirect on my website host running 4.4.8. It sends the email properly, but does not redirect, just continues to display the form. No change in the address bar either.
Thanks!
By Steve on Thu, 11 June, 2009