This sample contact form demonstrates how to implement a functional form with added security and backend processing. Below is an explanation of the process and the required files:
Form Submission Process:
- The contact form uses reCAPTCHA for spam prevention.
- Form data is sent via AJAX to avoid page reloads.
- The submitted data is validated and then inserted into the database.
- A confirmation email is sent using PHPMailer.
Required Files:
form.php:
This file contains the frontend HTML for the contact form. It includes reCAPTCHA and fields for user input.conn.php:
This file contains the database connection logic. It ensures secure and reusable database access throughout the application.commonajax.php:
This file processes the AJAX request. It validates the form data, verifies the reCAPTCHA, inserts the data into the database, and triggers the email process.mail.php:
This file handles the email-sending functionality using PHPMailer. You must upload the PHPMailer library for this to work.
form.php
<!DOCTYPE html>
<html>
<head>
<title>Contact Form</title>
<style>
/**** Alert Style ****/
.unstyled {
margin: 0;
list-style: none;
}
.unstyled a, .unstyled #test {
width: 120px;
text-decoration: none;
padding: .5em 1em;
background-color: #213347;
border-radius: 4px;
display: block;
margin-bottom: .5em;
font-size:15px;
font-weight:300;
font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
.unstyled a:hover, .unstyled #test:hover {
background-color: #f25c5d;
}
.cf, .alert {
*zoom: 1;
}
.cf:before, .alert:before, .cf:after, .alert:after {
display: table;
content: "";
line-height: 0;
}
.cf:after, .alert:after {
clear: both;
}
#alerts {
/*width: 400px;*/
top: 12px;
right: 50px;
position: fixed;
z-index: 9999;
list-style: none;
}
.alert {
width: 100%;
margin-bottom: 8px;
display: block;
position: relative;
border-left: 4px solid;
right: -50px;
opacity: 0;
line-height: 1;
padding: 0;
transition: right 400ms, opacity 400ms, line-height 300ms 100ms, padding 300ms 100ms;
display: table;
}
.alert:hover {
cursor: pointer;
box-shadow: 0 0 6px rgba(0, 0, 0, 0.3);
}
.open {
right: 0;
opacity: 1;
line-height: 2;
padding: 3px 15px;
transition: line-height 200ms, padding 200ms, right 350ms 200ms, opacity 350ms 200ms;
}
.alert-title {
font-weight: bold;
}
.alert-block {
width: 80%;
width: -webkit-calc(100% - 10px);
width: calc(100% - 10px);
text-align: left;
}
.alert-block em, .alert-block small {
font-size: .75em;
opacity: .75;
display: block;
}
.alert i {
font-size: 2em;
width: 1.5em;
max-height: 48px;
top: 50%;
margin-top: -12px;
display: table-cell;
vertical-align: middle;
}
.alert-success {
color: #fff;
border-color: #539753;
background-color: #8fbf2f;
}
.alert-error {
color: #fff;
border-color: #dc4a4d;
background-color: #f25c5d;
}
.alert-trash {
color: #fff;
border-color: #dc4a4d;
background-color: #f25c5d;
}
.alert-info {
color: #fff;
border-color: #076d91;
background-color: #3397db;
}
.alert-warning {
color: #fff;
border-color: #dd6137;
background-color: #f7931d;
}
/**** Alert Style End ****/
</style>
</head>
<body>
<form method="post" id="contact_enquiry_form">
<input type="text" name="firstName" placeholder="Full Name" required>
<input type="email" name="emailaddress" placeholder="Email Address" required>
<input type="number" name="phoneno" placeholder="Phone No." required>
<textarea name="message" placeholder="Message..." required></textarea>
<button type="submit">Submit Now</button>
</form>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://www.google.com/recaptcha/api.js?render=your_site_key"></script>
<script>
$(document).ready(function() {
$('#contact_enquiry_form').on('submit', function(e) {
//alert("Submit");
e.preventDefault(); // Prevent form submission
// Get reference to the submit button and disable it
var submitButton = $('.sec-btn-two');
var submitButtonText = $('.sec-btn-two span');
submitButtonText.text('Please Wait...'); // Change button text
submitButton.prop('disabled', true); // Disable the button to prevent multiple submits
// Get form field values
var name = $('input[name="firstName"]').val();
var phone = $('input[name="phoneno"]').val();
var email = $('input[name="emailaddress"]').val();
var message = $('textarea[name="message"]').val();
// Name validation: check if it's alphabetic and not empty
var nameRegex = /^[a-zA-Z\s]+$/;
if (!nameRegex.test(name)) {
Alert.warning('Warning! Please enter a valid name using only letters and spaces.', 'Warning', {displayDuration: 3000, pos: 'top'});
submitButtonText.text('Submit Now'); // Reset button text
submitButton.prop('disabled', false); // Re-enable the button
return; // Stop submission
}
// Phone validation: check if it's 10 digits
var phoneRegex = /^\d{10}$/;
if (!phoneRegex.test(phone)) {
Alert.warning('Warning! Please enter a valid 10-digit phone number.', 'Warning', {displayDuration: 3000, pos: 'top'});
submitButtonText.text('Submit Now'); // Reset button text
submitButton.prop('disabled', false); // Re-enable the button
return; // Stop submission
}
// Email validation: check for valid email format with stricter TLD validation
var emailRegex = /^[^\s@]+@[^\s@]+\.[a-zA-Z]{2,}$/;
if (!emailRegex.test(email)) {
Alert.warning('Warning! Please enter a valid email address.', 'Warning', {displayDuration: 3000, pos: 'top'});
submitButtonText.text('Submit Now'); // Reset button text
submitButton.prop('disabled', false); // Re-enable the button
return; // Stop submission
}
// Message validation: limit to 250 characters
if (message.length > 250) {
Alert.warning('Warning! Message should not exceed 250 characters.', 'Warning', {displayDuration: 3000, pos: 'top'});
submitButtonText.text('Submit Now'); // Reset button text
submitButton.prop('disabled', false); // Re-enable the button
return; // Stop submission
}
// Generate reCAPTCHA v3 Token
grecaptcha.ready(function() {
grecaptcha.execute('your_site_key', { action: 'contact_form' }).then(function(token) {
//var FormData = $('#contact_enquiry_form').serialize();
var FormData = $('#contact_enquiry_form').serialize() + '&g-recaptcha-response=' + token;
//console.log(FormData);
var from = "getintouch";
var enquiryfrom = "Contact Form";
//Perform AJAX
$.ajax({
type: 'POST',
url: 'commonajax.php?enquiryfrom='+enquiryfrom+'&from='+from,
data: FormData,
success: function (data) {
//alert("success--"+data);
//console.log(data);
if(data==1){
// Display success alert
Alert.success('Success! Your enquiry has been submitted successfully!. ','Success',{displayDuration: 3000, pos: 'top'});
// Optionally reset the form
$('#contact_enquiry_form')[0].reset();
}else{
//Alert.warning('Warning! Something went wrong, please try again later.','Warning',{displayDuration: 3000});
Alert.error('error! Something went wrong, please try again later.', 'Error', {
displayDuration: 3000,
pos: 'top'
});
}
// Reset the button text and re-enable the button after completion
submitButtonText.text('Submit Now');
submitButton.prop('disabled', false);
},
error: function () {
//alert("Error");
// Display error alert
Alert.error('error! There was an error submitting your enquiry. Please try again later.', 'Error', {
displayDuration: 3000,
pos: 'top'
});
submitButtonText.text('Submit Now');
submitButton.prop('disabled', false);
}
});
});
});
});
});
/***** Alert script ******/
var Alert = undefined;
(function(Alert) {
var alert, error, trash, info, success, warning, _container;
info = function(message, title, options) {
return alert("info", message, title, "fa fa-info-circle", options);
};
warning = function(message, title, options) {
return alert("warning", message, title, "fa fa-warning", options);
};
error = function(message, title, options) {
return alert("error", message, title, "fa fa-exclamation-circle", options);
};
trash = function(message, title, options) {
return alert("trash", message, title, "fa fa-trash-o", options);
};
success = function(message, title, options) {
return alert("success", message, title, "fa fa-check-circle", options);
};
alert = function(type, message, title, icon, options) {
var alertElem, messageElem, titleElem, iconElem, innerElem, _container;
if (typeof options === "undefined") {
options = {};
}
options = $.extend({}, Alert.defaults, options);
if (!_container) {
_container = $("#alerts");
if (_container.length === 0) {
_container = $("<ul>").attr("id", "alerts").appendTo($("body"));
}
}
if (options.width) {
_container.css({
width: options.width
});
}
alertElem = $("<li>").addClass("alert").addClass("alert-" + type);
setTimeout(function() {
alertElem.addClass('open');
}, 1);
if (icon) {
iconElem = $("<i>").addClass(icon);
alertElem.append(iconElem);
}
innerElem = $("<div>").addClass("alert-block");
alertElem.append(innerElem);
if (title) {
titleElem = $("<div>").addClass("alert-title").append(title);
innerElem.append(titleElem);
}
if (message) {
messageElem = $("<div>").addClass("alert-message").append(message);
innerElem.append(messageElem);
}
if (options.displayDuration > 0) {
setTimeout(function() {
leave();
}, options.displayDuration);
} else {
innerElem.append("<em>Click to Dismiss</em>");
}
alertElem.on("click", function() {
leave();
});
function leave() {
alertElem.removeClass('open');
alertElem.one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function() {
return alertElem.remove();
});
}
return _container.prepend(alertElem);
};
Alert.defaults = {
width: "",
icon: "",
displayDuration: 3000,
pos: ""
};
Alert.info = info;
Alert.warning = warning;
Alert.error = error;
Alert.trash = trash;
Alert.success = success;
return _container = void 0;
})(Alert || (Alert = {}));
this.Alert = Alert;
/***** Alert script end ******/
</script>
</body>
</html>
conn.php
<?php
/*PDO Connection*/
$servername = "your_server_name";
$username = "your_database_username";
$password = "your_database_password";
$dbname = "your_database_name";
try {
$pdo = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
// set the PDO error mode to exception
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//echo "Connected successfully";
}
catch(PDOException $e)
{
echo "Connection failed: " . $e->getMessage();
}
?>
commonajax.php
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
include 'mail.php';
include 'conn.php';
$from = $_REQUEST['from'];
$enquiryfrom = $_REQUEST['enquiryfrom'];
// echo $from."<br>";
// echo $enquiryfrom."<br>";
$secretKey = "your_recaptcha_secret_key"; // Replace with your reCAPTCHA Secret Key
$responseToken = $_POST['g-recaptcha-response'];
$remoteIP = $_SERVER['REMOTE_ADDR'];
// Verify the token with Google
$verifyURL = "https://www.google.com/recaptcha/api/siteverify";
$response = file_get_contents($verifyURL . "?secret=" . $secretKey . "&response=" . $responseToken . "&remoteip=" . $remoteIP);
$responseKeys = json_decode($response, true);
// Check verification result
if ($responseKeys['success'] && $responseKeys['score'] >= 0.5) {
// Proceed with form processing logic (e.g., save to DB, send email)
if ((isset($_REQUEST['from'])) && (isset($_REQUEST['enquiryfrom'])) && ($from != "") && ($enquiryfrom != "")) {
/***** Get In Touch *****/
if ($from == "getintouch") {
$Data = array();
$Data['enquiryfrom'] = $_REQUEST['enquiryfrom'];
$Data['firstName'] = $_POST['firstName'];
$Data['emailaddress'] = $_POST['emailaddress'];
$Data['phoneno'] = $_POST['phoneno'];
$Data['message'] = $_POST['message'];
//print_r($Data);
$task = array(':from' => $Data['enquiryfrom'], ':name' => $Data['firstName'], ':email' => $Data['emailaddress'], ':phone' => $Data['phoneno'], ':message' => $Data['message']);
//print_r($task);
$insert = "INSERT INTO `enquiry`(`from`, `name`, `email`, `phone`, `message`) VALUES (:from,:name,:email,:phone,:message)";
//echo $insert;
$run = $pdo->prepare($insert);
$run->execute($task);
if ($run) {
$From = "[email protected]";
$FromName = "Your Sender Name";
$EmailTo = "[email protected]";
$ToName = "Recipient Name";
$EmailToday = date('d/m/y');
$Subject = "Enquiry - " . html_entity_decode(ucfirst($Data['enquiryfrom']), ENT_QUOTES);
$Body = '<html>
<body style="background-color: #f9f9f9; width: 600px; padding: 30px; font-family: Arial, sans-serif; color: #333; line-height: 1.6;">
<div style="text-align: center; margin-bottom: 20px;">
<img src="your_logo_url_here" alt="Logo" style="max-width: 150px;">
</div>
<div style="background-color: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);">
<p style="margin: 0 0 20px; font-weight: 600; font-size: 14px;">Dear Team,</p>
<p style="margin: 0 0 20px; font-weight: 600; font-size: 14px;">'
. html_entity_decode(ucfirst($Data['firstName']), ENT_QUOTES) .
' has contacted us. Please get back to them soon.</p>
<table style="width: 100%; border-collapse: collapse; margin: 20px 0; font-size: 14px; color: #555;">
<thead>
<tr style="background-color: #f2f2f2; text-align: left;">
<th style="padding: 12px; border-bottom: 2px solid #ddd;">Field</th>
<th style="padding: 12px; border-bottom: 2px solid #ddd;">Details</th>
</tr>
</thead>
<tbody>
<tr>
<td style="padding: 10px; border-bottom: 1px solid #eee; font-weight: bold;">Enquiry for</td>
<td style="padding: 10px; border-bottom: 1px solid #eee;">'
. html_entity_decode(ucfirst($Data['enquiryfrom']), ENT_QUOTES) .
'</td>
</tr>
<tr style="background-color: #f9f9f9;">
<td style="padding: 10px; border-bottom: 1px solid #eee; font-weight: bold;">Name</td>
<td style="padding: 10px; border-bottom: 1px solid #eee;">'
. html_entity_decode(ucfirst($Data['firstName']), ENT_QUOTES) .
'</td>
</tr>
<tr>
<td style="padding: 10px; border-bottom: 1px solid #eee; font-weight: bold;">Email</td>
<td style="padding: 10px; border-bottom: 1px solid #eee;">'
. $Data['emailaddress'] .
'</td>
</tr>
<tr style="background-color: #f9f9f9;">
<td style="padding: 10px; border-bottom: 1px solid #eee; font-weight: bold;">Mobile</td>
<td style="padding: 10px; border-bottom: 1px solid #eee;">'
. $Data['phoneno'] .
'</td>
</tr>
<tr>
<td style="padding: 10px; border-bottom: 1px solid #eee; font-weight: bold;">Message</td>
<td style="padding: 10px; border-bottom: 1px solid #eee;">'
. html_entity_decode($Data['message'], ENT_QUOTES) .
'</td>
</tr>
</tbody>
</table>
<p style="margin: 20px 0 0; font-size: 13px; color: #888;">This is an automated email. Please do not reply to this email.</p>
</div>
</body>
</html>';
$AltBody = "This is an email for enquiry";
if (SendEmail($From, $FromName, $EmailTo, $ToName, $Subject, $Body, $AltBody)) {
echo 1;
} else {
echo 0;
}
} else {
echo 0;
}
}
}
} else {
echo 0; // Verification failed
}
?>
mail.php(email using the PHPMailer library, ensure to upload the necessary PHPMailer files.)
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require 'PHPMailer/src/Exception.php';
require 'PHPMailer/src/PHPMailer.php';
require 'PHPMailer/src/SMTP.php';
function SendEmail($From, $FromName, $EmailTo, $ToName, $Subject, $Body, $AltBody){
$mail = new PHPMailer;
$mail->SMTPDebug = false; // Enable verbose debug output
$mail->isSMTP();
$mail->Host = 'your_smtp_host';
$mail->SMTPAuth = true;
//$mail->Username = 'your_smtp_username'; // SMTP username
//$mail->Password = 'your_smtp_password'; // SMTP password
$mail->Username = 'your_smtp_username'; // SMTP username
$mail->Password = 'your_smtp_password'; // SMTP password
$mail->SMTPSecure = 'tls';
$mail->Port = 587;
$mail->From = $From;
$mail->FromName = $FromName;
$mail->addAddress($EmailTo); // Add a recipient
$mail->addReplyTo($From, $FromName);
//$mail->addBCC('[email protected]');
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = $Subject;
$mail->Body = $Body;
$mail->AltBody = $AltBody;
if(!$mail->send()) {
//echo 'Message could not be sent.';
//echo 'Mailer Error: ' . $mail->ErrorInfo;
return 0;
} else {
//echo 'new Message has been sent';
return 1;
}
}
?>
