Integrate the Google reCAPTCHA in PHP Contact Form
A CAPTCHA (Completely Automated Public Turing test to tell Computers and Humans Apart) is a type of challenge-response test used in computing to determine whether or not the user is human. In this tutorial, we have shared how to integrate the Google reCAPTCHA in PHP contact form.
Google reCaptcha helps you create a shield that protects your web application from spam and bots. This is a PHP library that wraps up the server-side verification step required to process responses from the reCAPTCHA service. This is a very simple script, you can copy-paste and modify it according to your requirement.
Downlod Google reCAPTCHA code library click here.
Register the domain of your website at Google reCAPTCHA Admin console.
- Label – choose label name.
- reCAPTCHA type – Select reCAPTCHA v2 >> I’m not a robot Checkbox
- Domains – Specify the domain of your website.
Get Site Key and Secret Key:
- Site Key : This key is used in the HTML code of the reCAPTCHA widget.
- Secret Key : This key helps to authorize communication between your site and the reCAPTCHA server.
Before started to implement the PHP Contact Form with Google reCAPTCHA, look files structure:
- php-contact-form-with-google-recaptcha
- css
- style.css
- library
- src
- autoload.php
- src
- config.php
- index.php
- contact.php
- css
include reCAPTCHA Widget to HTML Form
1 2 |
// google recaptcha js lib <script src='https://www.google.com/recaptcha/api.js'></script> |
Add tag g-recaptcha tag element in the HTML form where you want to display the reCAPTCHA widget.
- The g-recaptcha DIV element has a class (named
g-recaptcha"
) anddata-sitekey
attributes. - The Site Key of the reCAPTCHA API will be specified in the
data-sitekey
attribute.
Step 1: Create config.php
1 2 3 4 5 |
<?php //reCAPTCHA Configuration - go to Google and get the below keys http://www.google.com/recaptcha/admin define('SITE_KEY',"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); define('SECRET_KEY',"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); ?> |
Step 2: Create HTML Form
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
<?php require('config.php'); include('templates/header.php');?> <section class="showcase"> <div class="container"> <div class="pb-2 mt-4 mb-2 border-bottom"> <h2>PHP Contact Form with Google reCAPTCHA</h2> </div> <div class="row"> <span id="success-msg"></span> <div class="col"> <div class="card"> <div class="card-header bg-primary text-white"><i class="fa fa-envelope"></i> Contact us. </div> <div class="card-body"> <form method="post" class="contact-frm" id="contact-frm"> <div class="form-group"> <label for="name">Name</label> <input type="text" name="name" class="form-control input-contact-name" id="name" aria-describedby="nameHelp" placeholder="Enter name"> </div> <div class="form-group"> <label for="email">Email address</label> <input type="email" name="email" class="form-control input-contact-email" id="email" aria-describedby="emailHelp" placeholder="Enter email"> </div> <div class="form-group"> <label for="email">Contact No</label> <input type="email" name="phone" class="form-control input-contact-phone" id="email" aria-describedby="phoneHelp" placeholder="Contact no"> </div> <div class="form-group"> <label for="message">Message</label> <textarea name="content" class="form-control input-contact-email" id="message" rows="6" placeholder="How can we help you?"></textarea> </div> <div class="form-group"> <div class="g-recaptcha" data-sitekey="<?php echo SITE_KEY; ?>"></div> <span class="input-contact-captcha"></span> </div> <div class="mx-auto"> <button type="button" class="btn btn-primary text-right" id="info-contact">Submit</button></div> </form> </div> </div> </div> <div class="col-12 col-sm-4"> <div class="card bg-light mb-3"> <div class="card-header bg-success text-white text-uppercase"><i class="fa fa-address-card" aria-hidden="true"></i> Address</div> <div class="card-body"> <address> <h5>Customer service:</h5> <div title="Phone"><strong>Phone:</strong> +9 976 543 100</div> <div title="E-mail"><strong>E-mail: </strong><a href="mailto:contact@techarise.com" target="_top" rel="noopener noreferrer">contact@techarise.com</a></div> </address> <br> <hr> <br> <address> <h5>Head Office:</h5> <div>Company Inc, </div> <div>L/01 Rotterdam Rd East,</div> <div>89088 Southampton, United States</div> <div title="Phone"><strong>Phone:</strong> +9 976 543 100</div> <div><a href="mailto:contact@techarise.com" target="_top" rel="noopener noreferrer">contact@techarise.com</a></div> </address> </div> </div> </div> </div> </div> </section> <?php include('templates/footer.php');?> <script src='https://www.google.com/recaptcha/api.js'></script> <script type="text/javascript"> jQuery(document).on('click', 'button#info-contact', function(){ jQuery.ajax({ type:'POST', url:'contact.php', data:jQuery("#contact-frm").serialize(), dataType:'json', beforeSend: function () { jQuery('button#info-contact').button('loading'); }, complete: function () { jQuery('button#info-contact').button('reset'); jQuery('#contact-frm').find('textarea, input').each(function () { jQuery(this).val(''); }); setTimeout(function () { jQuery('span#success-msg').html(''); }, 3000); }, success: function (json) { //console.log(json); $('.text-danger').remove(); if (json['error']) { for (i in json['error']) { var element = $('.input-contact-' + i.replace('_', '-')); if ($(element).parent().hasClass('input-group')) { $(element).parent().after('<div class="text-danger" style="font-size: 14px;">' + json['error'][i] + '</div>'); } else { $(element).after('<div class="text-danger" style="font-size: 14px;">' + json['error'][i] + '</div>'); } } } else { jQuery('span#success-msg').html('<div class="alert alert-success">'+json['info'].text+'</div>'); } }, error: function (xhr, ajaxOptions, thrownError) { console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText); } }); }); </script> |
Step 3: Ajax code with with custom validation (include index.php)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
<script src='https://www.google.com/recaptcha/api.js'></script> <script type="text/javascript"> jQuery(document).on('click', 'button#info-contact', function(){ jQuery.ajax({ type:'POST', url:'contact.php', data:jQuery("#contact-frm").serialize(), dataType:'json', beforeSend: function () { jQuery('button#info-contact').button('loading'); }, complete: function () { jQuery('button#info-contact').button('reset'); jQuery('#contact-frm').find('textarea, input').each(function () { jQuery(this).val(''); }); setTimeout(function () { jQuery('span#success-msg').html(''); }, 3000); }, success: function (json) { //console.log(json); $('.text-danger').remove(); if (json['error']) { for (i in json['error']) { var element = $('.input-contact-' + i.replace('_', '-')); if ($(element).parent().hasClass('input-group')) { $(element).parent().after('<div class="text-danger" style="font-size: 14px;">' + json['error'][i] + '</div>'); } else { $(element).after('<div class="text-danger" style="font-size: 14px;">' + json['error'][i] + '</div>'); } } } else { jQuery('span#success-msg').html('<div class="alert alert-success">'+json['info'].text+'</div>'); } }, error: function (xhr, ajaxOptions, thrownError) { console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText); } }); }); </script> |
Step 4: Verify reCAPTCHA Response (using Server-side Validation)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
<?php require('config.php'); $json = array(); $user_name = filter_var($_POST["name"], FILTER_SANITIZE_STRING); $user_email = filter_var($_POST["email"], FILTER_SANITIZE_EMAIL); $user_phone = filter_var($_POST["phone"], FILTER_SANITIZE_STRING); $content = filter_var($_POST["content"], FILTER_SANITIZE_STRING); // name validation if(empty(trim($user_name))){ $json['error']['name'] = 'Please enter full name'; } // email validation if(empty(trim($user_email))){ $json['error']['email'] = 'Please enter email address'; } // check email validation if (validateEmail($user_email) == FALSE) { $json['error']['email'] = 'Please enter valid email address'; } // check conatct no validation if(empty(trim($user_phone))){ $json['error']['phone'] = 'Please enter contact no'; } if(validateMobile($user_phone) == FALSE) { $json['error']['phone'] = 'Please enter valid contact no'; } // comment validation if(empty($content)){ $json['error']['comment'] = 'Please enter comment'; } //reCAPTCHA validation if (isset($_POST['g-recaptcha-response'])) { require('library/src/autoload.php'); $recaptcha = new \ReCaptcha\ReCaptcha(SECRET_KEY, new \ReCaptcha\RequestMethod\SocketPost()); $resp = $recaptcha->verify($_POST['g-recaptcha-response'], $_SERVER['REMOTE_ADDR']); if (!$resp->isSuccess()) { $json['error']['captcha'] = 'Captcha Validation Required'; } } if(empty($json['error'])) { $toEmail = "contact@example.com"; $mailHeaders = "From: " . $user_name . "<" . $user_email . ">\r\n"; $mailBody = "User Name: " . $user_name . "\n"; $mailBody .= "User Email: " . $user_email . "\n"; $mailBody .= "Phone: " . $user_phone . "\n"; $mailBody .= "Content: " . $content . "\n"; /*if (mail($toEmail, "Contact Mail", $mailBody, $mailHeaders)) { $json['info'] = json_encode(array('type'=>'message', 'text' => 'Hi '.$user_name .', thank you for the comments. We will get back to you shortly.')); } else { $json['info'] = json_encode(array('type'=>'error', 'text' => 'Unable to send email, please contact'.SENDER_EMAIL)); }*/ $json['info'] = json_encode(array('type'=>'message', 'text' => 'Hi '.$user_name .', thank you for the comments. We will get back to you shortly.')); } header('Content-Type: application/json'); echo json_encode($json); // email validation function validateEmail($email) { return preg_match('/^[^\@]+@.*.[a-z]{2,15}$/i', $email)?TRUE:FALSE; } // mobile validation function validateMobile($mobile) { return preg_match('/^[0-9\-\(\)\/\+\s]*$/', $mobile)?TRUE:FALSE; } ?> |
This library comes in when you need to verify the user’s response. On the PHP side you need the response from the reCAPTCHA service and secret key from your credentials. Instantiate the
ReCaptcha
class with your secret key, specify any additional validation rules, and then call verify()
with the reCAPTCHA
response and user’s IP address.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?php //reCAPTCHA validation if (isset($_POST['g-recaptcha-response'])) { require('library/src/autoload.php'); $recaptcha = new \ReCaptcha\ReCaptcha(SECRET_KEY, new \ReCaptcha\RequestMethod\SocketPost()); $resp = $recaptcha->verify($_POST['g-recaptcha-response'], $_SERVER['REMOTE_ADDR']); if (!$resp->isSuccess()) { $json['error']['captcha'] = 'Captcha Validation Required'; } } ?> |
Create files named (header.php and footer.php)
This file contains the header and footer section of the webpage. The Bootstrap library is used to provide a better UI, so, include it in the header and footer section.
header.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="description" content=""> <meta name="author" content=""> <title>Integrate CCAvenue Payment Gateway using PHP | Tech Arise</title> <link rel="icon" type="image/ico" href="https://techarise.com/wp-content/themes/v1/favicon.ico"> <!-- Bootstrap core CSS --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css" /> <!-- Custom fonts for this template --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.7.2/css/all.min.css" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/simple-line-icons/2.4.1/css/simple-line-icons.css" /> <link href="https://fonts.googleapis.com/css?family=Lato:300,400,700,300italic,400italic,700italic" rel="stylesheet" type="text/css"> <!-- Custom styles for this template --> <link href="css/style.css" rel="stylesheet"> </head> <body> <!-- Navigation --> <nav class="navbar navbar-expand-lg navbar-dark bg-dark static-top header-bg-dark" style="background: ##FFFFFF!;"> <div class="container"> <a class="navbar-brand font-weight-bold" href="https://techarise.com"><h1>Tech Arise</h1></a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarResponsive"> <ul class="navbar-nav ml-auto"> <li class="nav-item active"> <a class="nav-link" href="https://techarise.com">Home <span class="sr-only">(current)</span> </a> </li> <li class="nav-item"> <a class="nav-link" href="https://techarise.com/php-free-script-demos/">Live Demo</a> </li> </ul> </div> </div> </nav> |
footer.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
<!-- Footer --> <footer class="footer bg-light footer-bg-dark"> <div class="container"> <div class="row"> <div class="col-lg-6 h-100 text-center text-lg-left my-auto"> <ul class="list-inline mb-2"> <li class="list-inline-item"> <a href="#">About</a> </li> <li class="list-inline-item">⋅</li> <li class="list-inline-item"> <a href="#">Contact</a> </li> <li class="list-inline-item">⋅</li> <li class="list-inline-item"> <a href="#">Terms of Use</a> </li> <li class="list-inline-item">⋅</li> <li class="list-inline-item"> <a href="#">Privacy Policy</a> </li> </ul> <p class="text-muted small mb-4 mb-lg-0">Copyright © 2011 - <?php print date('Y', time());?> <a href="https://techarise.com/">TECHARISE.COM</a> All rights reserved.</p> </div> <div class="col-lg-6 h-100 text-center text-lg-right my-auto"> <ul class="list-inline mb-0"> <li class="list-inline-item mr-3"> <a href="#"> <i class="fab fa-facebook fa-2x fa-fw"></i> </a> </li> <li class="list-inline-item mr-3"> <a href="#"> <i class="fab fa-twitter-square fa-2x fa-fw"></i> </a> </li> <li class="list-inline-item"> <a href="#"> <i class="fab fa-instagram fa-2x fa-fw"></i> </a> </li> </ul> </div> </div> </div> </footer> <!-- Bootstrap core JavaScript --> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/js/bootstrap.bundle.min.js"></script> </body> </html> |