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
Hi Sarah,
I am completely new to PHP and found your tutorial extremely easy to follow. I keep receiving the following error though at the bottom of the page which my contact form features on – PHP Notice: Undefined index: REQUEST_URI in D:\WebsiteFilePathGoesHere\contact-us.php on line 161. As a result the e-mail does not seem to be sending. Having undertaken some research I believe this may be something to do with IIS. Any ideas how to overcome this issue?
Many thanks,
Joe
By Joe P on Wed, 15 July, 2009
Hi Joe, yes IIS doesn't work with the REQUEST_URI setting for some reason. On line 161 you should find the form tag. look along until you see action="…" and delete everything between the double quotes. To save on validation then just replace with a # so you'll have action="#". Should fix the error
By Sarah on Thu, 16 July, 2009
Sarah, you are a star! Thank you.
By Joe P on Fri, 17 July, 2009
Hi Sara,
There is a problem with the regular expression for the field name. I am Greek and for Greek names, the script refuse to validate this field. Except to delete this pattern, i wonder if you have any other solution.
Sincerely,
Giannis
By Giannis on Thu, 6 August, 2009
Hi Giannis, Unfortunately I can't suggest much for the Greek letters. The regular expression should in theory cover those letters in the PHP 4.4+ version which I assume you're trying to use, but obviously it doesn't. I would just suggest to remove the check on line 65.
If you still wanted a check you would need to code a pattern to check the name entered against. In the PHP 4.0 version there is a simple english character check which you could maybe look at, or try looking on Greek PHP sites to look for a typical pattern to check if one or more words entered just contain letters.
The idea behind the check is to prevent characters that shouldn't be in a name eg. numbers, the @ sign, punctuation characters etc.
PS. In reply to your second comment, I didn't delete your first, it was just in the moderation queue.
By Sarah on Fri, 7 August, 2009
Hi Sarah (By the way you have one of my favorite names),
Thank you for your reply.
As a FeedBack, after a lot of coffee and happy boring reading, finally I found a working solution. So if anybody else cares to display correct Greek characters, here it is:
First step:
In Line 65, Find:
if (!preg_match('/^[p{L}-.\' ]+$/u', $formstuff['cfname'])) :
Then, Replace:
if (!preg_match('/^[x{0370}-x{03FF}]{3,15}$/u', $formstuff['cfname'])) :
//Comments for reading: This Regexp, allows only greek characters. The numbers between the brackets {3,15} allows only a range From 3 to 15 characters. I Added this as an extra security option, but it's optional and you can remove it though.
Second step:
In line 128, Find:
?>
After, Add:
meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
Third Step and happily the last one:
In Line 89, Change:
charset=ISO-8859-1n"
To:
charset=utf-8n";
However, I strongly believe that steps 2 and 3 (UTF-8 encoding) are useful, not only for the Greek language, but for everyone as well, and would constitute a better universal solution for non-latin characters and problems which arising from the different encodings, in generally.
As last words, I would like to thank you Sarah, for your nicely Contact script.
PS. Regarding to my second message, I figured out what was happening only when I submitted my second message and I noticed the moderation queue. I apologize for that.
Sincerely,
Giannis
By Giannis on Sun, 9 August, 2009
Hi Giannis, thanks for posting your solution
By Sarah on Fri, 21 August, 2009
Hell Sarah,
Maybe I got things backwards? I also tried another contact form and so far none work.
http://greenharmonyhome.com/contact.html
I'm so so with html and CSS but PHP is totally new. Any help to point me in the right direction would be great.
Mark
By Mark Vios on Sat, 22 August, 2009
Hi Mark, how is it that the form doesn't work? First off I'd recommend removing the brackets from the file name. contact-form.php would be fine. I just tried a test and it redirected to a 404. You need a thankyou.html page there.
Do you get the form results? Have you modified the top variables to add your email address in? It looks like it's working so without knowing what is and isn't working I can't suggest much more
By Sarah on Sat, 22 August, 2009
Hi Sarah,
I appreciate all your work and the clear instructions you have provided.
The only area I am tripping up is how to add the contact-form.php to my html file.
I tried bringing the contact form in via an iFrame and that worked, but I can't style the text.
In Dreamweaver I also tried Insert/Form/Method-Post/Action-Browsed and choose the contact-form.php form, but that didn't work either.
There has to be simple HTML coding in the Dreamweaver HTML file, to bring in the form, but I cant find it.
Can you help me?
Thanks!
By Marty on Thu, 24 September, 2009
Hi Marty,
The form is PHP and is virtually a self contained page, you just need to either add the HTML code for your header and footer around it, or put them into PHP includes and include them into the page.
I wouldn't try merging this in Dreamweaver as it's a manually written page and Dreamweaver will most likely change something and prevent the form from working.
Just above the form I have a comment saying 'insert your header or link to a header include here' and the same at the bottom for the footer. Put the relevant HTML that is required for the page layout/design at these two points and save it as contact.php (or something similar) and then it should be fine.
By Sarah on Mon, 28 September, 2009
Thanks Sarah,
I got it to work by pasting all the code into my HTML page (later renamed as a .php page) at the point you indicate (ie. comment saying 'insert your header or link to a header include here'), but at that point the form showed up below my CSS styled page.
I got it to work by cutting and pasting just the form ID (ie. <form id= ….etc.) and inserting where I wanted in my page. Yes worked!
Thanks for the tip on PHP includes which I will look into.
Thanks for the form. I like it as you showed me how to edit it to add new fields, and I learned a little more about php.
Thanks again!
Marty
By Marty on Mon, 28 September, 2009
Hi Sarah!
I just found your great blog…and this script.
I've got everything to work..and added a field.
Got the form pasted over some graphics background I wanted..and moved the fields around a bit…and maybe that's the problem.?
The script takes the entries, gives me the TY page…but I never receive notification back that a message was written.
I have the host email set to forward message back to personal email. T
he email address DOES work on its own…had the host check for problems. There are none.
So…I just can't get the email to notify me of a message received by forwarded mail.
It's not server side per the host…and again, the email forward works outside of the script.
Any ideas? I've been beating my head against the wall all day on this.
And CONGRATUALTIONS! on your recent marriage!
Thanks ever so much…this looks to be such a terrific script.
Cathy
By Cathy on Mon, 7 December, 2009
Hi Cathy,
Moving the fields is fine. Changing the PHP will cause it to stop working. Have you tried the basic original file again to see if that works for you? If it does then obviously a change you've made has caused the problem. If it doesn't then possibly it's missing something that your hosting requires in the code.
My guess is the original will probably work if it's set up correctly, so I'd need to see the code you're now using to see what's wrong with it.
By Sarah on Tue, 8 December, 2009
Hi Sarah
The form works great. I have been trying to delete the border but cannot find where to insert the code. On a new site I am building I want to keep the border but shorten it so it fits the page width.
Your help appreciated.
By Daviy on Sun, 20 December, 2009
Hi Daviy, do you mean the fieldset border? If so then you'll need to control the border size/look in your CSS stylesheet eg.
#contactform fieldset {border: 1px solid #666;
width: 400px;
}
which will control the colour and the width.
By Sarah on Sun, 20 December, 2009