A PHP Contact Form for your Site
Websites commonly require a contact form that allows site visitors to type a message that is then emailed to the site owner. For a “front end” web designer (who deals with things like HTML, CSS and the like) it’s easy enough to create the HTML form. But to get the form data entered by the visitor to actually be sent to the site owner, a “server side” script of some kind is needed.
A common server side language for processing form data is PHP. There are many different ways to write and set up PHP scripts for this purpose. I’ve made up two simple form processing scripts that you can use on your website. Which you use depends on your setup.
Please note that both scripts include a “honeypot” field that prevents spam bots from filling up your inbox. Likewise, each script includes security features that prevent spammers and bots from inserting malicious code into your form.
Internal Script for PHP-based Contact Pages
If your Contact page (the page that contains the contact form) has a .php
extension (such as index.php
or contact.php
), the script below is an option for you. Simply download the code and place it in your Contact page. You will also need to create a Thank You page. (Instructions are included in the download.)
External PHP Script for HTML-based Contact Pages
If your Contact page ends with a .html
extension and has been online for a while, you may prefer not to change the extension to .php
. Any links to the .html
page (such as those stored by Google) may give an error if you change to a new page—although you can fix this with a .htaccess
redirect.
So this alternate script runs externally to the Contact page, but does pretty much the same thing as the first script. Simply download the code and place the script page in the same folder as the Contact page. You will also need to create a Thank You page. (Instructions are included in the download.)
Extra Tips
- There are various tips for setting up your Contact page in the download files above, but something else to consider is the format of your page URLs. It’s much nicer for your contact page URL to appear as
mysite.com/contact/
rather than something likemysite.com/contact.html
. Here is a simple tip on making your URLs look nicer. - Of course, before you can use this form processing script, you need to ensure that your server actually has PHP installed … although it’s a rare host that doesn’t.
Legacy Comments
Thank you for the great tutorial and the downloads.
I have just come across the website and the content is very helpful specially if the reader is into web development.
The tutorials are practical and easy to follow. The writing style is very good.
I look forward to more learning in the future and also the Books For Learning. If you need any help in terms online marketing or programming give me a shout and I will volunter.
Thanks for the comments, Pali. The Books for Learning project is coming along very slowly, but hopefully I’ll get there.
thank u very much great script
Great tutorial. Very easy to use. Compliments
Came across your site whilst looking for an improved php contact form. Thanks for this it’s great. ISome very usefull CSS and other code items elsewhere on this site too.
You need to post more. Also you need an RSS feed so I (and others) can follow the sites updates in Google Reader, Feedly etc.
All the best.
Hi, is it possible to add a CC email address?
@Andy.
Thanks for the comments. I used to have an RSS feed, but decided not to include it in the latest update, as I don’t get the sense people use it much any more. Anyhow, will reconsider. And I do hope to post more soon.
@Matt
You can indeed add a CC email address. There are various ways.
One way is to send a separate email to the second person with the
mail()
function. Firstly, at the top of the form code, add a second email address:Then add another
mail()
line lower in the script, after the first one:But if you want a genuine CC address, where the first recipient sees that the email has been CCed to someone else, you can simply add an extra bit to the original
mail()
function, like this (see the end bit):Hope that helps.
PHP is basically lost on me from a coding perspective, so you my friend get a huge pat on the back! I’m using your very form on our website about house plants, and to anyone reading this: Ralph’s instructions are really straight forward and totally accurate. Thank you so much for doing this and helping people like us out.
How can i change sent to email address with address bar like:
http://site.com/contactform/[email protected]
It’s so important for me ... Thanks in advance.
@Yuccy Yucca—glad you found it useful. Thanks for the feedback!
@Hamed—I’m afraid I don’t quite understand the question. Can you say a bit more about what you are trying to do?
I’ve had a few prolems with this. All emails by this form sent to junk folder (spam). The second problem is sent content doesn’t support utf-8! Can you fix it? And also add a header mail for your contact form?
Thank you
Hello,
We have edited the email address in the process file, still not able to get an message in our inbox. Our server is with php support. Find the form here http://clickinwebstudio.in/contact/ but unable to get the mail in our inbox. Help.
@Click in webstudio
Hm, it looks like your setup is OK, although don’t forget to include the
thankyou.html
file as well.Did you also set an appropriate subject line? Make sure to check your spam folder, as some emails can be sent there is the subject line or contents seem to be fishy.
My concern is getting mail in my inbox. I have checked the spam folder and haven’t received the mail. Please fix the problem.
Looking up your domain, it seems you have Windows hosting, and I admit I don’t know how well this code will work on that platform. I’m only familiar with Apache. So that may be part of the problem.
I can’t really help much more without access to your site, as this is a backend issue. Feel free to contact me if you wish, though I may not be much use in a Windows environment. Unfortunately, there’s only so much help I can give in a comment thread. The code is basically given “as is”, I’m afraid, though I’m happy to help if I can.
Can you make this form support utf-8 in fields and comment? Can you add a subject field to this form? Can you make emails send to inbox instead of spam folder?
@Hamed—
Yes indeed. You can add the
Content-Type
to the fourth part of themail( )
function, like so:Yes. The form comes with a default subject line, which you add to the top of the script. If you want the user to be able to type a subject instead, you can add an extra form field. The easiest way to do this is to duplicate the Name field—both in the form and in the processing code, but changing the name, id etc. to something unique. Let me know if you have any trouble with that.
There are various things you can do. Firstly, make sure the subject line you choose is not spammy. Secondly, you can help convince email clients / mail servers that the email is coming from a respected source by setting up email authenticating with DKIM or creating and SPF record.
Hope that helps.
Ralph many thanks for your response. There is a problem with
preg_match()
. It doesn’t let me type in Arabic or Persian language, just English! It gives me this error in all field when I type like موضوع ایمیل:How can i fix it? :(
That’s a good question, Hamed!
I did a bit of googling, and it seems there are various ways to allow Arabic characters to pass through
preg_match()
validation, such as/^[\s\p{Arabic}]+$/u
. An example of this incorporated into the Name field would be this:An example of the comment field would be this:
These allow for various punctuation marks, English and Arabic letters etc. See if that helps. You’ll also need to update the error messages, such as this for the Name field:
Hi,
Thanks a lot for this script. I tried so many different ones and nothing was working.
Could you include reCaptcha Spam blocking option in it?
Then many people (including me) can just use this instead of other complicated options.
Hi saiko.
I’m not keen on CAPTCHA—no matter what the flavor. It penalizes the user as much as the spammer.
Instead, I’ve added a honeypot timer—a hidden field that compares the time of the page load and the time of submission. This will trip up bots while leaving your legitimate visitors alone entirely.
I’ve found that the “honeypot” method works really well to prevent bot spam. I never get any at all.
Thanks for your reply Ralph!
I totally agree with you about the issues with CAPTCHA. But I didn’t know there is such a simple and elegant solution to prevent spam! And also glad to find that it’s already implemented in your script
Thanks again for your script as it really helped!
Also, I really like the minimal and elegant design of your website, it complements your work!
Best Regards!
I’m glad you found this useful, saiko, and thanks for the compliment.
Thanks Ralph,
Judging by some of the ‘Help me, damn it!’ comments, I fear people may be forgetting you have created this and made it freely available out of the goodness of your heart and to help people (me included) who are either novices or have no server side script experience. I envy your patience.
I build static sites on AWS S3. Still a novice but I’m getting there, slowly. As I’m sure you know, because S3 is static, php isn’t usable, so I’ve always used ‘paid for forms’ hosted on the form companies servers, so I know I’ll be seeing the benefit of using your form. (I placed it on a free hosting site and will be linking to it through a lightbox from my site on S3.)
You’ve made it easy to use and the instructions are really spelled out and clear for us.
Thank you, It’s very much appreciated!! Good luck with the book!
Thanks very much, janoooosh! Your comments are appreciated, and your tips about S3 are very interesting.
hello,
I’ve popped this on my site and the code works beautifully but I am just not receiving any emails. I am running on a local server through MAMP. Any suggestions on what I need to do to receive the emails? tia
Hi kg. That’s a good question. I haven’t used this on MAMP before, but I’ve read that MAMP isn’t configured to do it by default. From what I’ve read online, you need to change a setting to allow emails to be sent. So give this a try and see if it works:
Go to your Applications folder, choose MAMP > conf > php5.3 (or whatever version you use) > php.ini (open this in your preferred code editor).
Then find the line that reads something like—
I’ve read various suggestions, from changing the second line to—
to doing this—
(Note that the
;
character must be removed from the start of the line.)The latter option will only allow you to email from your email back to your own email again, as I understand it. Make sure to save the php.ini file and to restart MAMP before you test the form again.
As I say, I haven’t tested this, but I really should! Anyhow, hope that helps.
Hi, I have installed the external version here http://www.avohai.com.br/contato.html but the emails are not being delivered. I have checked the spam folder also. Is there a way to debug what are happening to them?
Hi Dante. I don’t see the page there, but anyhow, one thing you can do is to place this code temporarily at the top of your PHP file:
That will hopefully show up and PHP errors. If that reveals nothing, I’d have to look at your setup to be able to get a better idea.
Hi, sorry, the correct link is: http://www.avohaibrasil.com.br/contato.html (the css is a little messy because I wan’t to make the form work first.)
I have added the “error_reporting(E_ALL|E_STRICT);” bit of code at the top of my process.php file and I didn’t show anything…
My thank you page is showing normally, but the emails are not being delivered. :/
OK, from a quick glance, the script seems to be working OK. So it might be something minor in your settings. If you want to send me your process.php file via email, I’ll have a look at it for you.
Please make it Cyrillic (Russian, Bulgarian) friendly i cant make it by my self
Hi spirobg. A similar question came up in this comment, where Arabic characters were involved. Similarly to that situation, you can add
\p{Cyrillic}
to thepreg_match()
lines to allow for Cyrillic characters.For future reference, here is a list that targets a wide range of languages.
If there is an error in the form, is there a method one could just echo only the form item rather than the complete htm page again?
What I mean is, echoing the incorrect form onto the existing page (presumably replacing the existing one) rather than refreshing and creating a whole new page.
Best regards
Andy
Hi Andy. Certainly with the ‘internal’ version of the script, the original form is echoed onto the same page, along with error messages, and you could just echo the bit that needs to be fixed and store the rest for sending ... although there may be times when the user will want to review other parts of the form. But with PHP, you still have to refresh the page.
Another option is to use JS on the front end to help with error messages etc., which would allow what you are asking for without a page refresh.
Both options are a bit beyond the scope of the basic code I’ve presented here, though.
I’m getting a parsing error on this line:
echo ‘<li>’.$err.</li>’;
Having major issues with the process.php
It works fine out of the box, but, when the echoed htm elements contain <?php include(“xxxx.php”); ?> items the process page stalls and just shows as white and no email is sent.
Any reason for this?
Also, should there be a closing php tag ‘?>’ on the process page?
Best regards
Andy
Hi Andy. I’m not sure what to say about the parsing error, except that something added to the page may be causing it?
In terms of the echoed content, you can’t have PHP inside that, but you can break the echo statement up into chunks, like so:
As for the closing
?>
, the recommendation is not to use it on files that just contain PHP, which is why I left it off, but it’s fine to put it back in there if you want.Many thanks Ralph - hopefully that should sort the echoed php items out.
It’s great code seriously - just need to make it work in my environment.
Cheers
A
No worries, Andy. Hoe it all works out, but feel free to follow up if needed. I’m no PHP expert, but see so many people who need contact form code that it seemed worth making something available. There are no doubt much better scripts out there, but this one works for my simple purposes.
Hi, tutorial is great, but when I click submit/send it brings the PHP up in the next webpage, and doesn’t complete the process. Have I done something obvious? I can’t figure out what I’ve done wrong.
Hi Ally. It sounds like PHP is not running on your site. To check what’s happening with PHP on your site, follow the instructions in my Checking Your PHP Configuration post. Good luck!
I have played with writing PHP and a tiny bit of MySQL for some time now but I have always wondered how to add the capabilities of including attachments to emails. I haven’t had much success on finding a tutorial or example though.
Hi Michael. Yes, that’s beyond the scope of the simple script I’ve posted here, but it involves allowing for file uploads. There’s a huge number of articles online about setting this up, such as this: http://webcheatsheet.com/php/file_upload.php
Hi! I followed your instructions and was FINALLY able to use the form on my webpage. I have it using
index.html
. However, I also have this same form on two other pages of my site.contact.html
andprojects.html
(my form is EXACTLY the same on these pages). I want those contact forms to work as well. I can’t seem to get them to work, just theindex.html
. I think it’s because in myprocess.php
I have$contact_page = “index.html”;
so it is only working onindex.html
. How can I make it work on the other two pages as well? Please help!Hi Jen. I’m glad you had some success. It’s odd, though, because all three pages should work. The problem probably isn’t the
$contact_page
setting, as that doesn’t really affect anything unless someone tries to go directly to theprocess.php
page.The main question is where those
contact.html
andprocess.html
pages are located. If they aren’t in the same folder as theindex.html
page, then they won’t be able to find theprocess.php
page if you just setaction=“process.php”
on the form, because that points to the same folder as the page the form appears on.If that’s the problem, then there are two options. Either change the action of the form to point to the process file (e.g.
action=”/contact/process.php”
etc.) or you could just duplicate theprocess.php
file and place one for each contact form in the same folder as the page calling that file.Hope that helps. Let me know if I’ve made the wrong assumption about your file setup.
EDIT: I tested your forms and they seemed to work OK. I see that all files are in the same folder. Did you get the emails I sent? I sent one from the Projects page and one from the Contact page.
Ralph -
I received your messages through my contact form - and tested all the pages - they work! I can’t tell you how much I appreciate you taking the time to have a look at my site and help me with this. You really are appreciated! THANK YOU so much!!!! Now I had better put some security on that form. PS I bookmarked this site
That’s great, Jen. Glad it’s all working. The form is quite secure as is, so you shouldn’t need any extra security. It locks down very tightly what users can enter, meaning that they can’t do anything malicious.
EDIT: I just checked, and I see you removed the hidden field that is there to catch bots. I recommend you add that back in. I’ve explained them a bit more in the Contact Form Honeypots post.
I’ve been hunting high and low for tutorials on how to make a contact form - yours is brilliant - thank you! Erm - I need to add three more fields beneath the Email address - one is for a telephone number, the other two are just for text. I’ve copied and amended the fields which show up on the form on the website, but I think I need to add some code to the process.php as the new field results aren’t included in the email I receive. Just wondering how I go about amending the process.php? The new fields will be “Telephone”, “Child’s Name” and “School Year”. Hope this makes sense!!
Hi Wendy. I’m actually in the process of writing a small, free ebook to show how to extend the form like this. In the meantime, here are some basic guidelines.
In the form code, when duplicating the fields you already have, you need to make sure that each has a unique
name=”“
value. (Also modify thefor=”“
andid=”“
for each label/input pair so that they don’t conflict with those of other pairs.)So Let’s say you end up with something like this:
In the
process.php
file, you then need to add a few things. Firstly, after$nam = $_POST[“name”];
, add these lines:Then, after this block of code:
add this:
I’m assuming above that each field will be required.
Below that, there’s the form that gets echoed if there’s an error. I’m sure you can update all that yourself by following the pattern of the other parts.
Finally, amend the
$email_body
section to this:With any luck, that will do it!
Thanks a million for your reply Ralph - you really are a star! I look forward to your ebook - I’ll certainly make good use of it.
I’m going to follow your instructions tomorrow and will let you know how I get on.
The internet can be a brilliant place to learn!
Thanks again,
Wendy
A very good and simple form. Thank you.
I’m not sure that the HTML document wide ID value is allowed with the textarea tag in HTML5?
http://www.w3schools.com/tags/tag_textarea.asp
This ID value is used for the multiple row comments form area (achieved with textarea), for example:
Any ideas on how to achieve HTML5 compliance for this?
Hi Mikey. Thanks for your comments.
IDs are classed as “global attributes”—which means they can be placed on all HTML elements, so it’s certainly fine to include one here (desirable, in fact, because it associates the textarea with the label—thanks to the
for
attribute).The list of HTML5 attributes you linked to are new ones for HTML5, but certainly not the only ones.
Ralph - you were so incredibly helpful with my contact form I thought I would ask you another question. I would like to make my site tablet and mobile friendly. Where should I go to learn?
Thanks!
Hi Jen. The first thing I’d recommend is to look into “responsive web design”, for which there are many resources, such as the article I linked to, and various books and online courses and videos.
Hope that helps.
The problem is, any user can spam you. Click back any time and it send it again and again :(
Hi Laura. Not really sure what you mean. It’s very hard to send spam via a form like this. The most someone can do is annoy you a bit, but there’s no security thread in that. What do you mean by ‘click back’? If you close the page or move to another one, the form inputs are cleared away.
If you mean that the user can click the back button and resubmit the form again and again, then that’s true. The internal version has a timer on it, though, which means the spammer would have to wait each time to be able to resubmit—and I doubt most spammers have that kind of patience. There’s only so much you can do to stop people annoying you, and in my experience, I’ve not seen someone submitting the same thing over and over, so I suspect it’s not common. There’s really nothing for a spammer to gain from it.
Hi it’s just me again.
How about a form that has “name”, “email” and a text area for a question like: “Theatre Interests”. Can this be written in html, then powered up through php, then have the information stored in a mysql? Thought I’d ask!
Hi Jen. You definitely can store form data in a database, or even just in a flat file. This is beyond the scope of this simple form, though. A good resource for learning about this sort of thing is Kevin Yank’s book PHP: Novice to Ninja.
Installed and is working correctly, but I’m not receiving the emails. Nothing in the spam folder, and I added the error_reporting line to the process.php file, but it does nothing. I removed the spam test fields, that’s the only mod I made on your code. Any ideas? PHP permissions maybe? I’m hosted at Hostgator, so I’m sure PHP is installed.
Thanks for your help.
Hi Dave. Sounds odd. The one circumstance where I’ve seen this happen is when you enter the same email address as the form data will be sent to. Try sending the form with a made up email address—or at least something different from the address to which the form data will be sent.
Got it solved Ralph. For some reason it didn’t like the email address I was sending to. Its my domain email, routed to gmail. Maybe gmail didn’t like it … don’t know.
Thanks again
Dave
That’s great. Glad you found a solution, Dave!
I am using the external version and am wondering how I can make the error page be the same format as the rest of my site. Like having it redirect to a page called “Oops!” with the error text displayed there similar to how the thank you page works.
Hi Kathy. Great question.
There are various things you can do. You could, for example, redirect to a static page on your site that informs the user that there was an error, perhaps with a list of things to watch for … although that’s not very helpful. You would do that by changing this section (starting line 52 in
process.php
)—to this
… where
errorpage.html
is the path to your error page.However, in the
process.php
page from line 52, you see all the HTML code for the current error page. A nicer option is to replace the HTML parts with your current site’s HTML/CSS, so that you keep the current error page—with the user’s errors actually listed—along with your site’s own styles and layout. Just place this error code wherever you want in your template:… and keep the class (
class="err"
) on theul
if you need to.Does that make sense?
I installed the internal version.
The website is old and has Frontpage extensions installed.
The contact.php file and thankyou.html are in the root directory.
contact.php displays properly in a browser.
When I submit the info, I get an error:
Follow up:
Although I never get to the thankyou.html page after I click submit, I DO get the message delivered to my email address.
Hi Adean. Did you modify the file in any way, other than adding in the appropriate email address etc? As noted in this explanation of PHP header errors, the error message is telling you that the problem is on line 1 of the contact.php file, and it’s probably a case of there being some whitespace before the opening
<?php
, which is not allowed. Could you check that?Thank you, I have it working now. I just recopied and updated the index.html file.
Gmail will not deliver the messages but Yahoo Mail will. Any thoughts?
Hi Dave. I think you mean that GMail isn’t receiving the emails? They work fine in GMail for me, so it might be worth checking your spam folder. If they are being received at Yahoo, it sounds like the form code is working fine, and that something else is going on elsewhere. It may be worth adding SPF records and or DKIM authentication for your email account(s).
Thanks Ralph, I got it working. Google Apps was reading the “your email address” as the from address and rejecting it. So I added another email that has sever domain in it and it works fine now. The bottom of process.php looks like this now.
Thanks Dave. I have found it can be a problem to test the form by entering the same email address as the address the form data will be sent to. That shouldn’t necessitate changing the form code, thought. To test the form, just enter any email address other than your own—even a fake one. Not sure if that’s the situation you were facing, though.
Hey Ralph, the Google apps problem was not with my email address. It was with every other email address.
Thanks for the feedback, Dave. Not totally sure what’s going on there, but glad you found a solution. I use Google Apps too and haven’t run into any issues.
Hey Ralph great script thanks for sharing it. Why are the @ $ not allowed in the comments section. Thanks, Dave
Hi Dave. I guess that’s just how I felt on the day. They can be used for spam and code injections, so it’s really up to you what you do and don’t allow.
Hi, thank you for the tutorial. I am creating my first website and am grateful to use your code for a contact page. My problem is that when I submit the page I always get an error that the Comment is entered incorrectly. I added an echo statement to the process.php file to echo the $com field and it looks okay. Any ideas?
Hi Melissa. I can’t really say what might be going awry for what you’ve said, but I’d be happy to take a look if you like. Perhaps just get in contact directly.
I love your script, especially since I’m finding less people wanting to bother users with CAPTCHA, so it leaves me searching for a plan B. However, most of my forms send to different email addresses based on what is selected on the form (I pass a variable called “recipients” which contains the email address to send to. So, my question is this : could I substitute the static email address in the process.php file = $your_email = “[email protected]”; with my variable recipients? I’ve tried (please know I’m no PHP prodigy though!) and anytime I try to modify the page with a variable (or simply print_r($_POST); to see if the variables are making it), I get the error message of “Warning: Cannot modify header information - headers already sent by ....”. Would LOVE to use this solution though. I’d hate to start my search over! Thanks!
Hi CSINIA. It’s actually quite easy to set up the form so that it can send to various recipients based on what’s selected in the form, but it’s a bit beyond the scope of this simple post. If you want, post your form code and indicate which part of it determines the email choice.
Hi Ralph. I think this is what you’re looking for…. So, if people want to contact a certain individual, there may be a link by their name. The link would be:
On the
Contactform.php
page, there is a default PHP script in case the emailto variable is empty for some reason:Then I pass it as a hidden field to a php file which is supposed to strip characters.
Again, I am no PHP guru, and it probably shows. Let me know if there’s a way I can get your PHP file to recognize my “recipients” variable. If I’m barking up a wrong tree, just let me know. Thanks!
Hi CSINIA,
The way I’ve done that in the past is to include a select list in the form (or you could use check boxes if you want multiple recipients) and then in the processing script take a look at who was selected and use the associated email address for that selection as the recipient of the email.
As a simple example, let’s say you add this to the form:
Then, in the PHP, something like this:
Then you establish the recipient:
Hey Ralph, your form works really well. How can we add a file upload to it. Thanks, Dave
Hi Dave. File uploading is a different animal altogether, and I’m not qualified to guide you on that. There are lots of online guides, though, including this one from the SitePoint forums. Sorry I couldn’t be more help, but personally I’m not too keen on allowing file uploads anyway (for security reasons etc.). I’d rather establish email contact with someone first and then perhaps share files via email.
Hi there, Ralph. Thanks for this brilliant script and your useful walkthrough. Is it, in any way, possible to leave out a thank-you-page and put the thank-you-message on the formpage itself?
Thanks in advance.
Hi Ron. Thanks for your comments.
Yep, it’s quite straightforward to do that. You can just replace this line:
with something like this:
Of course, you can make it a lot more sophisticated than that, including all the layout and styles you want, but this is the basic idea.