Web projects are divided into back-end and front-end work, so web designers don’t have to worry about the “scary” programming, but what about simple presentational websites, where web designers can single-handedly work on, but inevitably get stuck on the contact page.
At that point, most either ask a PHP programmer to do the contact form’s PHP processing or implement an open source contact form somewhere from the web.
But! What if we learn how to actually create one from scratch, eh?
Not only it would help you easily manage smaller projects, but also have a better understanding how PHP form validation and processing works and can help you better tweak other scripts out there.
Now, there are countless ways to build and validate a form, but for this lesson’s sake, I’ve chosen to build most of the code in a single contact file, plus, it will give us one small benefit at the end, you’ll see.
So let’s get started! Right below, you have a basic non-fancy HTML contact form.
contact.php
style.css
- Things to know:
- Our contact page has the .php extension so it can expect and process PHP code;
- The form has an ‘action’ attribute, it specifies the file that’s going to send the form’s data to, since we’re going to do most of the work inside the same document, we specified the current document: contact.php;
- The attribute ‘method’ is the way we want our data to be handled and sent, we specified ‘POST’ as it’s a more invisible way to send the data, the alternative is ‘GET’, though GET will display the data in the URL and we don’t want that;
- All HTML form fields have a ‘name’ attribute, PHP uses the values from the name attributes to fetch their data.
We need to make sure that our PHP code will only be run if the form has been submitted, to do so, we’re going to insert our code inside a PHP function that detects whether the visitor has clicked or not the submit button.
From this point on, we’ll start checking whether all fields have been filled and add them to variables which we can further use, or add errors in case of non-filled fields.
We’ll need an empty $error variable which we can add the error messages to in case there will be any:
We have ‘name’ as the first field, let’s validate it by adding:
Like I mentioned earlier, we’ve used the POST method to handle the form’s data, we can fetch the fields’ values by using $_POST['name_of_field'], also, we used the ‘empty’ PHP function to check whether the fields are empty or not. The litteral translation of the above code would be: IF the name field is not empty, then add the name field’s value to the $name variable, but if it’s empty (ELSE), then add to the $error variable “You didn’t type in your name. <br />”. Knowing that we may have more field errors to display, all messages have a break tag at the end so each will be displayed on a new line.
Validating the e-mail address field is going to be a bit more tricky, because not only that we have to check whether the visitor has inserted one, but also if it’s a valid e-mail address:
Don’t panic! That whole preg_match “mumbo-jumbo” haha, is actually a line of code you might never have to change when validating e-mails. Don’t worry about remembering the exact code, even skilled programmers have it saved somewhere ready to copy paste ![]()
Now, the only difference from the name validation code, is that we added a secondary IF statement to also check whether the e-mail entered is valid, that being done with the preg_match function.
If you’re interested to know though, preg_match uses given regular expressions against a value and returns whether it matches or not. In our case, we used preg_match to make sure that:
But like I said, you can save that preg_match function somewhere and use it whenever you want to validate an e-mail field/value.
Next up and last field is the ‘message’ textarea, we validate it just like we did with the ‘name field’:
And that’s a wrap with the fields validation, here’s what we have so far:
There’s just one step left to do, determine whether the form has been filled properly and send the message, or the visitor encountered errors.
Here’s the logic, along the validation process, in case the visitor has failed to either fill in all the fields or add a valid e-mail address, we added error messages to the $error variable, all we have to do is check whether the $error variable has messages in it, basically, if it’s empty or not. If it’s indeed empty, we can go ahead and prepare to send the message:
Sending an e-mail with PHP’s mail() function is quite easy as you can see in the last line of code, all we need to know is where to send it, the e-mail’s subject, the content and where it came from. We’ve added the needed variables including the success message. Make sure you change ‘my@email.com’ with yours.
Though the above code won’t be executed if the visitor has encountered errors, thus $error no longer is empty. We need to determine where we want to add the error messages, I personally want them between the h2 tag and the form:
Yet, just another ‘if-and-else’ statement where we check if $error is not empty and echo the $error messages we added along the way, else (if it’s empty), then the mail was sent and we echo the $success variable which we added previously.
And there you have it, a functional PHP contact form! Here’s the final code:
contact.php
If you’ll look at the HTML form again, you’ll notice some PHP code in the fields.
Many complain that PHP is not a good main form validator, because it clears the form even when the visitor encounters errors and has to refill it again. Well, not exactly, because we added the PHP processing in the same file with the html form, we now have access to the fields’ values via $_POST['name_field']; and we can assign those values back in the fields. Voila, no more form refill stress!
The form is now fully functional, you can use it assured, but I say something’s missing. Guessed it? SPAM protection!
Nowadays, you can’t put up a public form without receiving countless spam e-mail messages.
You can either stop here, or quickly learn how to add captcha protection to the form.
We’ll make the captcha script in a separate file called captcha.php and we’ll also need to make a few minor changes to contact.php afterwards.
captcha.php
I’ve added comments on each line and I believe the code is already self-explanatory and you can tweak the values as needed. What’s to notice, is that now we’re using sessions so we can save the generated code on the server and validate it in the form, similar to how we used $_POST['name'];
The files that work with sessions, they need to start with session_start();, that really has to be the very first line the document starts with, nothing must come before it. So both captcha.php and contact.php need to have <?php session_start(); ?> at the very beginning.
Now we need to add another HTML form field for the captcha, right before the submit button:
We used captcha.php as the image source, because, well… it is an image. The captcha PHP script we’ve made generates an image and captcha.php behaves like one.
Lastly, we’re going to validate the code that the visitor enters, like we did with the other fields, we’re going to add another ‘if-and-else’ statement below the other ones:
Looks familiar? Not far from validating the name field I guess, we fetch the code the visitor enters using POST and validate it against the code we saved it on the server via $_SESSION['code'];, if it fails to validate, just add another error message to $error. And that’s a wrap!
Here’s the final code with captcha:
style.css
captcha.php
contact.php
Too add more required fields in the form is quite easy, for example, if we’d need one more field for the visitor’s phone number, we’ll add another html form field:
Another if-and-else statement along the others:
And add the $phone variable in the content variable which gets sent:
The code is 101% free to use, a backlink is optional but highly appreciated, it would give this article more exposure to other readers out there
Thank you! I did try to get into as much details as possible, I was, however, worried at some point not to make my readers dizzy heh, I’m glad you enjoyed it.
good job, very detailed information, thank you. Just want to know how to display distorted text?
I’ve tried to keep the entire process as simple as possible, using a more advanced captcha system worried me that it might confuse the readers along the process ![]()
I’ll, however, consider writing a separate article about a more complex captcha, though this one should do just fine, unless you’re running a highly solicited web company ![]()
Thanks for the feedback!
I went through the process quite thoroughly, and after understanding each and every part, and constructing my files, I cannot get it to execute! Have any suggestions? Your article was very good and explained very well. I thought I could execute php file if I had php executable specified, but I keep getting code in all the fields. Thx much.
I assume you’re trying to run the php files locally on your computer. To do that, you’ll need to install a local web server, you can achieve that by installing the WAMP server for windows or LAMP for Linux, there’s also XAMPP which has support for all operating systems. An easier way would be to run the files on a hosting account.
Really great article on building a PHP contact form from scratch. I particularly liked how you gave the examples and diagrams, they were very useful.
Love your site man keep up the good work
I am to a great extent impressed with the post. I recommend it.
Thanks Buddy! I truly enjoy the information that? you’re sharing bruh! Extremely simple to comprehend.
This post is very interesting, I like it. I will always come to visit after.I would recommend to friends more.
It’s what I’ve tried to focus one, I’m glad you found them useful!
Then my goal has been accomplished!
enormous post you keep
Hehe this is the longest article from DevIngredients so far
It’s hard to stuff in so many details in a short article
Very much informative post. I like it. Thanks for sharing in the web.
Thanks a lot. Very helpful in my situation – Keep up!
Hello there, I trust you, should you found yourself in Romania you’ve got a light beer via us: ) Regards!
Hi, currently making a website with a contact form page, I’ve got my page layout all done and called it contact.html, i’ve copied you css into my style sheet, copied the captcha page and inserted all the php into my page where i want the form, but when the form comes up it’s covered in php script, i’m guessing this is because all the files are in the same folder? What does it mean that it’s server side aswell, when i try open it? You don’t have to explain that bit though, ill try find an article on it.
Thanks for the post though, it’s help me a lot, sure I’ve just missed something!
That’s because you haven’t renamed your contact.html file to contact.php
PHP will only be parsed if the file extension ends in .php
So go ahead and rename your contact page and it should work just fine!
Let me know how it turns out for you
Hi – thanks for getting back to me so quickly. Just tried that but still getting the same problem,
All this text is over and around the form:
“Your message was NOT sent
The following error(s) returned:
‘ . $error . ‘
‘; } elseif (!empty($success)) { echo $success; } ?>
Name: Email: Message:
”
Along with some other php script in the text fields. Been using HTML and CSS a few years, but this is the first time I’ve wanted to make a contact form and worked with PHP.
I just went on and assumed you were running your files on a hosting server or a local one for that matter, but I guess you’re not. PHP can’t be run without apache/PHP.
If you have a hosting account, run your files there and they should work. If not, try XAMPP, it’s a free local web server which you can do all of your PHP/MySQL work under.
Best of luck!
I have successfully added your form in my web site. But i found a small mistake. Email’s that have ” _ ” are not valid
for example:
smart_man@yahoo.com and yet such emails exist.
Could u send me just that corrected part of the code via email.
Tnx in advance.
Ah yes! Thanks for noticing that Igor, it looks like I’ve missed the first underscore rule. Here’s the new pregmatch expression:
(!preg_match(“/^[_a-z0-9]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/i”, $email))
The files have been updated here as well.
Post back if this worked for you
great script, one of the best so far I’ve found online
.. but i have some questions regarding space:
how can i combine the php “value” variable:
<input type="text" name="email" value="” />
with this variable:
I don’t want to have the description outside of my form fields but I’d like to have them inside since i do not have that much space on the website.
furthermore – what is the correct pregmatch expression for checking the phone number field and only allowing “0-9″ (?!):
(!preg_match(“/^[0-9]/i”, $phone))
i deeply appreciate your support.
thanks again
cybo
PS: here again since it seems it killed the script
hope this works now ..
great script, one of the best so far I’ve found online
.. but i have some questions regarding space:
how can i combine the php “value” variable:
input type=”text” name=”phone” value=”(?php if ($_POST['email']) { echo $_POST['email']; } ?)
with this variable:
value=”Your Phone Number” onFocus=”if (this.value == ‘Your Phone Number’) this.value = ”;” onBlur=”if (this.value == ”) this.value = ‘Your Phone Number’;”
I don’t want to have the description outside of my form fields but I’d like to have them inside since i do not have that much space on the website.
furthermore – what is the correct pregmatch expression for checking the phone number field and only allowing “0-9″ (?!):
(!preg_match(“/^[0-9]/i”, $phone))
i deeply appreciate your support.
thanks again
cybo
I’m glad you liked it Cybo!
To validate an ‘only numbers’ field, you can use (!preg_match(“/^[0-9]/”, $phone)) yes
I’m not sure you really want to be so strict about phone number validation, such as forcing a format xxx-xx-xxxx etc I personally had too many complaints how clients couldn’t manage adding the phone number to a form ![]()
One thing you can do though is to force it to a certain length, if you know your visitors’ phone number area, then just ask for a certain length:
(!preg_match(“/^[0-9]{10}/”, $phone))
The number in between those curly brackets requires the value to have a 10 number length number and you can eventually add an example of a phone number they’re able to add.
Regarding your other inquiry, I’ll e-mail you, too much for a comment
Good luck!
hey catalin.
awesome! thanks for your reply. i didn’t receive en email by now, so please use the one off this post
this should arrive for sure!
Great input. I only wanted to validate “numbers only” – since you are right a too tough restriction might end up in a customer “jump off” mentality
have a wonderful sunday!
cybo.
Hey, quick question about the captcha, I followed your tutorial to the letter, and made sure that I understood each part before moving on. My only problem is that when the captcha is correct there is an error, but when the captcha is wrong, the message is sent. With my limited knowledge of php, I am having a hard time figuring out why this is, especially because my code is identical to yours and is correct as far as I understand it. Any ideas would be gratly appreciated.
please disregard my previous comment, I had simply forgotten to start my contact page with the php session_start(). Thanks anyway.
I’m glad you solved it! Good to have this pointed out for the others
I resent the e-mail to both addresses, hope you get it now and hope it helps you fix your problem
Cheers
Even though I am not good at customizing/developing a site, but I know how to admire the works of a skillful web developer. And the article that you have posted here is very informative and compelling. And I might try myself it too.
How do I get the form to send me the user ip address and browser?
Thanks
In the PHP code add two more variables:
$ip = $_SERVER['REMOTE_ADDR'];
$browser = $_SERVER['HTTP_USER_AGENT'];
Those will detect the IP and Browser user agent and add them to those variables (which you can name however you want).
All you have to do now is include those variables in the e-mail’s $content variable.
$content = $name . ” has sent you a message: \n” . $message . “\n IP: ” . $ip . “\n Browser:” . $browser;
And now the e-mails will also contain the sender’s IP address and browser agent.
Excellent. Now how do I get the form fields to go away and show only a success message after a successful sent?
This contact page has not been constructed to do that, however, it’s not hard! But not that easy to explain in a comment either. I’m willing to mail or chat the solutions with you.
I’ll e-mail you several ways we can communicate.
I got it working for the most part. Although I’m having a problem with the captcha.
I enter the right code but I still get an error that says the code is incorrect.
I believe you missed a vital step, if you read carefully, I’ve mentioned that your contact page needs to start with:
< ?php session_start(); ?>
See if that fixes the problems
Hi, great tut and thanks for sharing.
I think I understand everything but seem to be having the same trouble. I have at the top and tried changing CHMOD but still not validating the captcha.
On the latest version of my xampp local host, the form works fine but the email doesn’t get sent. When uploaded to a web server all variables work except the captcha doesn’t validate and email is only sent when field is empty.
Anything else come to mind?
Cheers
I will have to ask again, are you absolutely sure your contact.php page starts at the very beginning with < ?php session_start(); ?> ? No spaces before it, nothing.
If you’re sure, then perhaps you can send me your files to catalin (at) devingredients (dot) com, so I can figure out where you messed up
Also, always test your final contact form on a real host, xampp and other local servers do not send e-mails unless properly set to do it.
Looking forward to hearing from you.
Thanks Catalin,
So I double checked to make sure there’s no spaces and that session_start is at the very beginning of the page. Yea I kinda figured I didn’t set up outgoing on my local.
I sent the site files for the contact page. Thanks so much for your help, It’s greatly appreciated!
Cheers
So the form trouble got solved. It was in fact a hosting server issue. I had to edit the session.save_path for my account and edit the .htaccess file. The form works great. Thanks for sharing this and for all of your help.
Cheers
Fantastic Griff, you’re very welcome.
I’m glad you worked things out in the end, great job!
Cheers
I seem to be having the same problem as the gentleman above. My contact form is included into my entire layout through a php script (to have pages like index.php?page=contact). For one, the form action needs to be removed as it does not work with index.php?page=contact.
This means I need to open my session on the index page, which isn’t a problem. However when browsing to the contact form (thus loading index.php and having contact.php included through a require(), it keeps coming up saying the code is wrong. When I however enter an incorrect code or just press send after having gotten the error the code is wrong, it sends the message just fine. Pretty frustrating.
I *could* use the form without the captcha, but I’m worried to be receiving a lot of spam.
Cheers!
That’s the exact reaction as if the page does not have session_start at the beginning. Knowing your method of dealing with the site’s inner pages, it’s a bit difficult figuring out what can cause that. If the site doesn’t contain sensitive data, you can try mailing me the files so I can test them myself, perhaps clearing the content before sending them.
I can mail you the website. It does not contain any sensitive information. If you give me an e-mail address then I will mail the entire website zipped (or rarred, whichever you like).
Cheers!
You can send me your zipped files to catalin (at) devingredients (dot) com
Problem solved, mail sent with the solution.
Can a dropdown be added to the code ?
For exampleif you want to ask-
How did you find us(below are the options to give)
from a friend
search engine
dumb luck
saw the link at another place
Thanks,bud
By the way,this is by far the best and easiest tutorial how to make a form using captcha and php that I come accross.
It took me a while to find it but I did and the onlything I would consider adding to it would be as my previous post asks,the ability to put a select list dropdown or a radio/checkbox(which could have multiple answers selected)
Awesome job explaining and linking mockups for us to use.
Thanks,
Bud
That’s very easy friend, question is though: Do you simply want to have the dropdown selection sent in your e-mail (regardless if it was selected or not), or to validate the field and force the user to select an option?
The process to add a dropdown is the same as you do with inputs. At the end of the tutorial I explained how you can add extra fields and what extra PHP code is needed, just add a dropdown instead
Example:
< select name="source" >
< option>< /option >
< option>From a friend< /option >
< option>Search engine< /option >
< option>Dumb luck< /option >
< option>Saw the link at another place< /option >
< /select>
P.S. Don’t copy the above code, I added extra spaces to evade code parsing.
The reason I added a blank option at the beginning is so the user can get an error in case (s)he didn’t select an option.
If you don’t wish to force the user to select an option, then just remove the blank option and add a default one (i.e. < option > No selection < /option >)
Now, let me know if you manage, if not, I’ll probably help you via e-mail.
Cheers
I got the select form to work just fine .thank you for that.
I was also wondering how I would have to do the code to select from a list of choices (check boxes and get multiple answers returned.(such as checking all that apply …)
Thanks,
Bud
Hi i’ve installed wamp and im getting errors and code is beuing displayed in the text boxes.. am i doing something wrong
Not at all. Only wamp displays those errors.
If you’ll run the files on a public hosting server, the form should work just fine.
Also on wamp, if you’ll submit the form leaving the fields empty, the errors inside the boxes will disappear.
This can be fixed and I’ll update the files very soon.
I have incorporated your contact form into my contact page. However, when I try to send an e-mail, I keep getting the error about captcha code not matching . . . ?
? has been included on contact.php page.
I sincerely hope you can help! Thank you so much for your time.
Elva
Make sure that at the very beginning of your contact page, the code starts with: < ?php session_start(); ?>
if not, add it, it should work then
has been added at the top of the contact.php page (no spaces).
With that in mind and with the code in this blog, it should work. So there must be something on your page that stops the form from processing the verification code. I’m willing to take a closer look at your code if you’re willing to send the page (and the related script/php files) over at catalin (at) devingredients (dot) com
Remove confidential info as needed.
Is there any way to make this clear the form data once its submitted. The form action is pointing to the same page as the contact form, since everything on my site is on one page. So after submit the data gets sent fine and thank you message is displayed however the data still remains. I know usually you could do something like value = “” so when page loads form data would be blank for each item, however since value points the php variables I’m not quite sure how to clear. Any help would be appreciated. Thanks
You’ll notice that as long as the form is submitted and no errors are given, a few variables are written. We can check if one of those variables exist, if they do, that means the form will get sent and we can stop PHP echoing the data in our form fields.
So let’s just check whether the $success variable is empty and only echo data as long as it’s not, since $success is written only when the form gets submitted successfully.
So our name field would be come from this
< ?php if ($_POST['name']) { echo $_POST['name']; } ?>
to this
< ?php if ($_POST['name'] && empty($success)) { echo $_POST['name']; } ?>
Do the same for the other fields.
So now they’ll be filled as long as the form does not get sent.
Let me know if you manage.
Thanks, great job..
Hi Catalin,I see some site changes-mostly color and I like it.Keep up with the awesome tutorials.I do appreciate all of the help you provided me in making my feedback form
Thanks bud! It was a pleasure helping you.
I thought it was time for a change and I like how this theme is turning out as well. “The beautiful gray!”
Looking forward to having more free time to focus on the blog.
Hi, how would i add check boxes to this script, i’ve added the dropdowns ok
One of the best form tutorial in web.
@AJN
Thank you! I’m glad it helped you.
I have always struggled with contact forms, but today I created my own for a work project, and it is slick! Couldn’t have done it without this tutorial. Nice work!
Thanks for creating this tutorial. I followed the guide and created the contact form, after going live with the page, I enter my contact info and message, hit send and get the Thank you, message was sent. It all appears successful. But the messages are not arriving at the specified email address. Not trapped in spam folders either. Anyway ideas to troubleshoot?
You’re very welcome!
Did you make sure that your contact page starts at the very beginning with < ?php session_start(); ?> ?
Try adding a wrong captcha code intentionally, does it still succeed?
I can have a look at the code if that’s alright with you. Have all the necessary files zipped and sent to catalin (at) devingredients (dot) com
Cheers
Also, just wondering if you would be so kind as to share how you got feedburner to pop up with the subscription when I entered my comment too? And if you are willing to share, would it work with Disqus on a blog? Thanks again.
This is exactly what I was looking for – thanks! Nice job, you made it easy to understand.
11:55 AM
Thank you for this information, its really complete and good.