PHP Contact Form with HTML Emails & Optional Captcha (Anti-Spam)

PHP Contact Form with HTML Emails & Optional Captcha (Anti-Spam)

By Aaron F. April 7th, 2015


While there are many things that all modern websites should have, one of the most important pieces to that is a functional contact page.

A contact page is often times the portal your clients & users have to easily get in touch with you. This means that your contact form should be strait forward, easy to use, and function entirely within the website & server itself. This means no ugly "mailto" links, which can cause additional user issues in the event the user does not have a mail client configured.

That being said, contact forms do have their own set of issues, mainly spam. Spambots scan the web not only for email address (ahem, mailto links anyone?) but also for contact forms with standard form names like name, email & message, from which they can automatically fill in the details and send you a message. While your actual email address is not accessible to the bot, there is nothing preventing said bot from revisiting your contact page and sending you more spam.

With this script, I have not only created a simple & easy to implement contact form, but I have also added a simple captcha (anti-spam) option to prevent bots from sending you unwanted email. The captcha is optional, and can be enabled/disabled at will from the configuration options. This script is also self contained to a single page & has form error checking. Let's dive into the script so we can get a further understanding of how it functions.


<?php // BEGIN CONFIGURATION //////////////////////////////////////////////// define('EMAIL_TO', ''); define('EMAIL_SUBJECT', 'Email Subject'); define('CAPTCHA_ENABLED', '1'); // 0 - Disabled, 1 - Enabled // END CONFIGURATION ////////////////////////////////////////////////// define('CAPTCHA1', rand(1,9)); define('CAPTCHA2', rand(1,9)); if ($_POST) { $name = $_POST['name']; $email = $_POST['email']; $message = $_POST['message']; $captcha = $_POST['captcha']; $captcha1 = $_POST['captcha1']; $captcha2 = $_POST['captcha2']; // If captcha disabled, set variable values to avoid error if (CAPTCHA_ENABLED == '0') { $captcha1 = '1'; $captcha2 = '1'; $captcha = '2'; } // Error handling if (empty($name) || empty($email) || empty($message)) { $msg = 'One or more fields is blank!'; } else if (!$email == '' && (!strstr($email,'@') || !strstr($email,'.'))) { $msg = 'Your email address is not formatted correctly!'; } else if (($captcha1 + $captcha2) != $captcha) { $msg = 'Anti-spam incorrect! Please try again.'; } // Build email headers else { $headers = "From: ".$name." <".$email.">\r\n"; $headers .= "Reply-To: ".$name." <".$email.">\r\n"; $headers .= "MIME-Version: 1.0\r\n"; $headers .= "Content-Type: text/html; charset=UTF-8\r\n"; // Build email body $body = ' <html><body> <table border="0" cellspacing="0" cellpadding="0" width="100%"> <tr><td style="border-bottom: solid 1px #CCC; font-size:18px; font-weight:bold; padding:10px;" colspan="2">'.$email_subject.'</td></tr> <tr><td valign="top" style="padding:10px; border-bottom: solid 1px #CCC;" valign="top"><b>Name:</b></td><td style="padding:10px; border-bottom: solid 1px #CCC;">'.$name.' ('.$email.')</td> </tr> <tr><td valign="top" style="padding:10px; border-bottom: solid 1px #CCC;" valign="top"><b>Message:</b></td><td style="padding:10px; border-bottom: solid 1px #CCC;">'.$message.'</td></tr> </table> </body></html>'; // Send the email, reset text boxes on form, and show success message mail(EMAIL_TO, EMAIL_SUBJECT, $body, $headers); $name = ''; $email = ''; $message = ''; $msg = 'Message Sent!'; } } ?>

Lines 2 - 8: Use this section to configure your contact form. This includes options such as where the contact form will email to, the subject of that email, and whether or not to enable the captcha (anti-spam) option. Configure these options to suit your needs.

Lines 10 & 11: This defines what variables to use in the captcha. In this case, these lines of code generates two random numbers between 1 and 9. In order to successfully submit the contact form, the user must answer a simple math question (i.e.: 4 + 9 = ?). These lines define what those two numbers will be.

Lines 13 - 19: This is where our script captures the data submitted on the form. Name, email address & message are all strait forward. As for the captcha, what happens when the page is loaded is there are three form fields created for the anti-spam portion. Two of these are hidden, and one is visible. The two that are hidden will each have their respective values set to the random numbers that we generated above. The visible field is where the sum of those two numbers must be entered. The two hidden fields and their respective values are also shown in the label for the anti-spam box.

Line 22: This line is only in place in the event you want to disable captcha. This line prevents the script from giving an error message when captcha is disabled.

Lines 25 - 27: This is where our error handling occurs. All error messages can be customized with HTML. Line 25 checks for any blank fields. If a field is blank, a standard error message will be shown. Line 26 checks whether the email address entered is formatted correctly. All email addresses must have an "@" (at) and a "." (dot). Line 27 is where the captcha is calculated. We already have both single digit numbers that are to be added together. This line does some basic math; if the first digit + the second digit does NOT equal what is entered by the user, show an error. In this case, if the captcha was 8 + 8 and the answer entered was anything other than 16, display the error message and do not send the email.

Lines 30 - 45: If the form has no errors, we now move onto building the actually email. Lines 31 through 34 set the email headers. This is where we specify that the email body will consist of HTML code. Lines 37 through 45 is where we build the actual body of the email. You can include any HTML code here that you like. However it is worth mentioning that best practices dictate not to use any external files (CSS, images, etc) in the body of your message, because in the event you do not have an internet connection, your email will not render as expected.

Lines 48 - 53: This is the portion of the script that actually sends the message. It includes the email address & subject as set in our configuration. This section also resets all text boxes on the form to a blank value, and finally displays the successfully sent message.


<!DOCTYPE HTML> <html> <head> </head> <body> <?php echo $msg; ?> <form method="post"> Name:<input type="text" name="name" value="<?php echo $name; ?>" /> Email:<input type="text" name="email" value="<?php echo $email; ?>" /> Message:<textarea name="message" rows="5" cols="40" /><?php echo $message; ?></textarea> <?php if (CAPTCHA_ENABLED != '0') { ?> <?php echo CAPTCHA1; ?> + <?php echo CAPTCHA2; ?> = ? <input type="text" name="captcha" /> <input type="hidden" name="captcha1" value="<?php echo CAPTCHA1; ?>" /> <input type="hidden" name="captcha2" value="<?php echo CAPTCHA2; ?>" /> <?php } ?> <input type="submit" value="Submit" /> </form> </body> </html>

Lines 57 - 61, 78 & 79: Standard opening & closing HTML tags for the contact page.

Line 63: This is where all of the messages we configured in the PHP portion will appear. This can be moved around on the page to anywhere you feel it should be, as long as it appears AFTER the PHP portion.

Lines 65 - 76: This is our actual form. You'll notice that the first three lines are strait forward; name, email & message. Also note the "value=..." potion. This is where the PHP code above will display any options that have already been entered into these fields after the form is submitted, in the event of an error. There is no sense forcing the user to fill out all options again if they made a mistake somewhere. We only want to clear these fields in the event the form is successfully submitted.

Lines 69 - 74: This is our captcha portion. In the event you have turned captcha off in the configuration, this section does not render at all. If captcha is turned on, line 67 is visible to the user. This is where the user must enter the answer to the captcha question. Line 68 and 69 are where the digits for the captcha are captured but hidden, and submitted with the form so our PHP can process the captcha/anti-spam equation. Again, if the answer to the captcha does NOT equal the sum of these two numbers, the submission will fail and the user will have to re-enter the captcha answer with two new numbers.


Custom Error & Success Messages: For each error & success messages in our PHP, you will see a portion of code like "$msg = '...';" change where "..." is to customize your messages. You can add HTML styling, DIVs, images, etc to each message as required.

Remove Captcha Altogether: Download the file above, open it, and delete lines 6, 10 & 11, 17 to 19, 27, and 69 to 73.


This is a simple, versatile & easy to implement script that you are free to download and use on any website you maintain. Of course, this page must be hosted on a PHP enabled server.

If you have any questions, please contact me and I will help any ways I can!

Topics: Web Design & Development