User Registration with Email Verification in php

Hey Technoz, Hope you are doing Great! We have seen many websites uses email verification technique to avoid spam mails. In this post, we’ll also discuss about this topic. When the user registration or sign up is done, the verification email is sent to his/her email (using phpmailer library) from which he/she can verify the account.

As we are creating email verification using phpmailer library, I recommend you to go through following tutorial first to see how phpmailer works.

Send email with phpmailer library

1. Creating Database

As we have to do user registration, we have to create the database to store the values entered by user. Use the following query to create the database, table and required fields in it.

DROP TABLE IF EXISTS `users`;
CREATE TABLE IF NOT EXISTS `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) NOT NULL,
  `password` varchar(255) NOT NULL,
  `email` varchar(100) NOT NULL,
  `verification` varchar(50) NOT NULL DEFAULT 'pending',
  PRIMARY KEY (`id`)
)

The above query will create a new table ‘users’ with fields id, name, password, email, verification. Furthermore, The first four fields will store data entered by user, while last field will have default value as ‘pending’. So, user registration will be pending at start.

2. Making connection with database

Create the following file config.php for connection with database.

<?php
$servername = "localhost";
$username = "root";
$password = "";

try {
    $conn = new PDO("mysql:host=$servername;dbname=registerwithemail", $username, $password);
    // set the PDO error mode to exception
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    }
catch(PDOException $e)
    {
    echo "Connection failed: " . $e->getMessage();
    }
?>

3. Download phpMailer library

After user registration, we have to do email verification. We are using phpmailer library to send email as it is easy to use and has guaranteed email delivery. Download it from this link.

After downloading, extract the zip and put the ‘phpmailer’ folder in root directory of your project.

4. Creating User Registration form

Now, we’ll start coding our actual form for user registration. Lets create file index.php and paste the following php code in it.

<html>
<head>
<title>User Registration with Password Verification in php | Technopoints</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
</head>
<body>
<div class="container">
<center>
<h1>User Registration with Email Verification in php | Technopoints</h1><br/>
<div class="w3-container w3-blue">
  <h2>Registration Form</h2>
</div>
<form action="" method="post" class="w3-container">
	<p>
	<input class="w3-input" type="text" placeholder="Enter Name" name="name" required />
	<p>
	<input class="w3-input" type="password" placeholder="Choose Password" name="password" required />
	<p>
	<input class="w3-input" type="email" placeholder="Enter Email" name="email" required />
	<p>
	<p><button type="submit" name="registerbtn" class="w3-btn w3-block w3-red w3-center-align">Register</button></p>
</form>
<!--php code for registration-->
<?php
include "config.php";
$msg="";
if(isset($_POST['registerbtn'])){
	require_once "phpmailer/class.phpmailer.php";
	$name=$_POST['name'];
	$email=$_POST['email'];
	$password=$_POST['password'];
	
	$sql = "SELECT COUNT(*) AS count from users where email = :email";
  try {
    $stmt = $conn->prepare($sql);
    $stmt->bindValue(":email", $email);
    $stmt->execute();
    $result = $stmt->fetchAll();

    if ($result[0]["count"] > 0) {
      $msg= "Email already exist";
      $msgType = "warning";
    } else {
      $sql = "INSERT INTO `users` (`name`, `password`, `email`) VALUES " . "( :name, :password, :email)";
      $stmt = $conn->prepare($sql);
      $stmt->bindValue(":name", $name);
      $stmt->bindValue(":password", password_hash($password, PASSWORD_DEFAULT));
      $stmt->bindValue(":email", $email);
      $stmt->execute();
      $result = $stmt->rowCount();


      if ($result > 0) {
       
        $lastID = $conn->lastInsertId();
		
		$url="http://localhost/registerwithemail/activate.php?id=" . base64_encode($lastID) . "";
		$message=" 
<html>
  <head>
    <meta name='viewport' content='width=device-width' />
    <meta http-equiv='Content-Type' content='text/html; charset=UTF-8' />
    <title>Simple Transactional Email</title>
    <style>
      /* -------------------------------------
          GLOBAL RESETS
      ------------------------------------- */
      img {
        border: none;
        -ms-interpolation-mode: bicubic;
        max-width: 100%; }

      body {
        background-color: #f6f6f6;
        font-family: sans-serif;
        -webkit-font-smoothing: antialiased;
        font-size: 14px;
        line-height: 1.4;
        margin: 0;
        padding: 0;
        -ms-text-size-adjust: 100%;
        -webkit-text-size-adjust: 100%; }

      table {
        border-collapse: separate;
        mso-table-lspace: 0pt;
        mso-table-rspace: 0pt;
        width: 100%; }
        table td {
          font-family: sans-serif;
          font-size: 14px;
          vertical-align: top; }

      /* -------------------------------------
          BODY & CONTAINER
      ------------------------------------- */

      .body {
        background-color: #f6f6f6;
        width: 100%; }

      /* Set a max-width, and make it display as block so it will automatically stretch to that width, but will also shrink down on a phone or something */
      .container {
        display: block;
        Margin: 0 auto !important;
        /* makes it centered */
        max-width: 580px;
        padding: 10px;
        width: 580px; }

      /* This should also be a block element, so that it will fill 100% of the .container */
      .content {
        box-sizing: border-box;
        display: block;
        Margin: 0 auto;
        max-width: 580px;
        padding: 10px; }

      /* -------------------------------------
          HEADER, FOOTER, MAIN
      ------------------------------------- */
      .main {
        background: #ffffff;
        border-radius: 3px;
        width: 100%; }

      .wrapper {
        box-sizing: border-box;
        padding: 20px; }

      .content-block {
        padding-bottom: 10px;
        padding-top: 10px;
      }

      .footer {
        clear: both;
        Margin-top: 10px;
        text-align: center;
        width: 100%; }
        .footer td,
        .footer p,
        .footer span,
        .footer a {
          color: #999999;
          font-size: 12px;
          text-align: center; }

      /* -------------------------------------
          TYPOGRAPHY
      ------------------------------------- */
      h1,
      h2,
      h3,
      h4 {
        color: #000000;
        font-family: sans-serif;
        font-weight: 400;
        line-height: 1.4;
        margin: 0;
        Margin-bottom: 30px; }

      h1 {
        font-size: 35px;
        font-weight: 300;
        text-align: center;
        text-transform: capitalize; }

      p,
      ul,
      ol {
        font-family: sans-serif;
        font-size: 14px;
        font-weight: normal;
        margin: 0;
        Margin-bottom: 15px; }
        p li,
        ul li,
        ol li {
          list-style-position: inside;
          margin-left: 5px; }

      a {
        color: #3498db;
        text-decoration: underline; }

      /* -------------------------------------
          BUTTONS
      ------------------------------------- */
      .btn {
        box-sizing: border-box;
        width: 100%; }
        .btn > tbody > tr > td {
          padding-bottom: 15px; }
        .btn table {
          width: auto; }
        .btn table td {
          background-color: #ffffff;
          border-radius: 5px;
          text-align: center; }
        .btn a {
          background-color: #ffffff;
          border: solid 1px #3498db;
          border-radius: 5px;
          box-sizing: border-box;
          color: #3498db;
          cursor: pointer;
          display: inline-block;
          font-size: 14px;
          font-weight: bold;
          margin: 0;
          padding: 12px 25px;
          text-decoration: none;
          text-transform: capitalize; }

      .btn-primary table td {
        background-color: #3498db; }

      .btn-primary a {
        background-color: #3498db;
        border-color: #3498db;
        color: #ffffff; }

      /* -------------------------------------
          OTHER STYLES THAT MIGHT BE USEFUL
      ------------------------------------- */
      .last {
        margin-bottom: 0; }

      .first {
        margin-top: 0; }

      .align-center {
        text-align: center; }

      .align-right {
        text-align: right; }

      .align-left {
        text-align: left; }

      .clear {
        clear: both; }

      .mt0 {
        margin-top: 0; }

      .mb0 {
        margin-bottom: 0; }

      .preheader {
        color: transparent;
        display: none;
        height: 0;
        max-height: 0;
        max-width: 0;
        opacity: 0;
        overflow: hidden;
        mso-hide: all;
        visibility: hidden;
        width: 0; }

      .powered-by a {
        text-decoration: none; }

      hr {
        border: 0;
        border-bottom: 1px solid #f6f6f6;
        Margin: 20px 0; }

      /* -------------------------------------
          RESPONSIVE AND MOBILE FRIENDLY STYLES
      ------------------------------------- */
      @media only screen and (max-width: 620px) {
        table[class=body] h1 {
          font-size: 28px !important;
          margin-bottom: 10px !important; }
        table[class=body] p,
        table[class=body] ul,
        table[class=body] ol,
        table[class=body] td,
        table[class=body] span,
        table[class=body] a {
          font-size: 16px !important; }
        table[class=body] .wrapper,
        table[class=body] .article {
          padding: 10px !important; }
        table[class=body] .content {
          padding: 0 !important; }
        table[class=body] .container {
          padding: 0 !important;
          width: 100% !important; }
        table[class=body] .main {
          border-left-width: 0 !important;
          border-radius: 0 !important;
          border-right-width: 0 !important; }
        table[class=body] .btn table {
          width: 100% !important; }
        table[class=body] .btn a {
          width: 100% !important; }
        table[class=body] .img-responsive {
          height: auto !important;
          max-width: 100% !important;
          width: auto !important; }}

      /* -------------------------------------
          PRESERVE THESE STYLES IN THE HEAD
      ------------------------------------- */
      @media all {
        .ExternalClass {
          width: 100%; }
        .ExternalClass,
        .ExternalClass p,
        .ExternalClass span,
        .ExternalClass font,
        .ExternalClass td,
        .ExternalClass div {
          line-height: 100%; }
        .apple-link a {
          color: inherit !important;
          font-family: inherit !important;
          font-size: inherit !important;
          font-weight: inherit !important;
          line-height: inherit !important;
          text-decoration: none !important; }
        .btn-primary table td:hover {
          background-color: #34495e !important; }
        .btn-primary a:hover {
          background-color: #34495e !important;
          border-color: #34495e !important; } }

    </style>
  </head>
  <body>
    <table border='0' cellpadding='0' cellspacing='0' class='body' style='padding-top:2%'>
      <tr>
        <td>&nbsp;</td>
        <td class='container'>
          <div class='content'>

            <!-- START CENTERED WHITE CONTAINER -->
            <span class='preheader'>New Contact Form Entry.</span>
            <table class='main'>

			<tr>
                <td class='wrapper'>
                  <table border='0' cellpadding='0' cellspacing='0'>
                    <tr>
                      <td><center>
                        <p><img src='https://softglobe.net/img/icon.png' width='70%' height='20%'></p>
						<p><h2>New user registration</h2></p></center>
                      </td>
                    </tr>
                  </table>
                </td>
              </tr>
			  
              <!-- START MAIN CONTENT AREA -->
              <tr>
                <td class='wrapper'>
                  <table border='0' cellpadding='0' cellspacing='0'>
                    <tr>
                      <td>
                        <p>Hi, $name</p>
                        <p>We have received a new signup request from this email address.</p>
                        <p>Click on the button below to confirm your email address.</p>
						<p> <center><a href=".$url." target='_blank' style='width:80%; display: inline-block; color: #ffffff; background-color: #3498db; border: solid 1px #3498db; border-radius: 5px; box-sizing: border-box; cursor: pointer; text-decoration: none; font-size: 14px; font-weight: bold; margin: 0; padding: 12px 25px; text-transform: capitalize; border-color: #3498db;'>Verify Email</a></center></p>
                        <p>Thanks for registring with us.</p>
						<p>If you have not performed this activity, then please ignore this email.</p>
                      </td>
                    </tr>
                  </table>
                </td>
              </tr>

            <!-- END MAIN CONTENT AREA -->
            </table>

            <!-- START FOOTER -->
            <div class='footer'>
              <table border='0' cellpadding='0' cellspacing='0'>
                <tr>
                  <td class='content-block'>
                    <span class='apple-link'>Technopoints, Maharashtra, India 445001</span>
					<br> This is mandatory service email sent to you by Technopoints.
                  </td>
                </tr>
                <tr>
                  <td class='content-block powered-by'>
                    Powered by <a href='https://technopoints.co.in'>Technopoints</a>.
                  </td>
                </tr>
              </table>
            </div>
            <!-- END FOOTER -->

          <!-- END CENTERED WHITE CONTAINER -->
          </div>
        </td>
        <td>&nbsp;</td>
      </tr>
    </table>
  </body>
</html>";
        
		
        // php mailer code starts
        $mail = new PHPMailer(true);
        $mail->IsSMTP(); // telling the class to use SMTP

        //$mail->SMTPDebug = 0;                     // enables SMTP debug information (for testing)
        $mail->SMTPAuth = true;                  // enable SMTP authentication
        $mail->SMTPSecure = "tls";                 // sets the prefix to the server
        $mail->Host = "mx1.domain.com";      // replace with your SMTP server
        $mail->Port = 587;                   // set the SMTP port for the your server

        $mail->Username = 'mail@example.com'; //put your email address here
        $mail->Password = 'XXXXXX'; //put the password here

        $mail->SetFrom('mail@example.com', 'Organization'); //replace with your values
        $mail->AddAddress($email);

        $mail->Subject = trim("Email Verification - Technopoints"); //email subject body
        $mail->MsgHTML($message);

        try {
          $mail->send();
          $msg = "Successfully Registered! Please verify your email.";
          $msgType = "success";
        } catch (Exception $ex) {
          $msg = $ex->getMessage();
        }
      } else {
        $msg = "Failed to create User";
        $msgType = "danger";
      }
    }
  } catch (Exception $ex) {
    echo $ex->getMessage();
  }
}
?>
<!--End of registration code-->
<?php
if ($msg <> "") { ?> 
  <div class="alert alert-dismissable alert-<?php echo $msgType; ?>">
    <a href="#" class="close" data-dismiss="alert" aria-label="close">&times;</a>
      <center><b><?php echo $msg;?></b></center>
  </div>
  <?php } 
?>

<i style="width:100%; color:red;">Powered by <a href="https://technopoints.co.in">Technopoints</a></i>

</center>
</div>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<script  src="js/index.js"></script>
</body>
</html>

Let me explain the above file. The file contains a simple form which takes input as name, email and password. After submitting a form, the code checks whether the user already exists in database. If so, it shows error and stops. Besides that, If there is new entry, the new user entry is created in database and simultaneously, the email is sent to the entered email address using phpmailer library. Do not forget to change the following credentials with yours:

$mail->Username = 'support@technopoints.co.in'; //put your email address here 
$mail->Password = 'XXXXXX'; //put the password here 
$mail->SetFrom('support@technopoints.co.in', 'Technopoints'); //put your email address

Lets see the index page in the image below

User Registration with Email Verification in php

Have a look below of received email

User Registration with Email Verification in php

The $message variable in the index file contains all the well-formatted email body which is to be sent to the recipient. We also have to activate the user’s account after clicking on verify email button in an email. We have provided a link to a button, which calls the file, which contains the code for account activation. Note the line below stated in index file:

$url="http://localhost/registerwithemail/activate.php?id=" . base64_encode($lastID) . "";

The link is generates using id of the user. To maintain the security, we have encoded the id using base64_encode() function.

5. Email Verification using phpmailer library

To activate the account, we have to code file activate.php as follows.

<html>
<head>
<title>User Registration with Password Verification in php | Technopoints</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body>
<center>
<?php
require_once 'config.php';

if (isset($_GET["id"])) {
  $id = intval(base64_decode($_GET["id"]));
 
  $sql = "SELECT * from users where id = :id";
  try {
    $stmt = $conn->prepare($sql);
    $stmt->bindValue(":id", $id);
    $stmt->execute();
    $result = $stmt->fetchAll();

    if (count($result) > 0) {

      if ($result[0]["verification"] == "verified") {
        $msg = "Your account has already been activated.";
        $msgType = "info";
      } else {
        $sql = "UPDATE `users` SET  `verification` =  'verified' WHERE `id` = :id";
        $stmt = $conn->prepare($sql);
        $stmt->bindValue(":id", $id);
        $stmt->execute();
        $msg = "Your account has been activated.";
        $msgType = "success";
      }
    } else {
      $msg = "No account found";
      $msgType = "warning";
    }
  } catch (Exception $ex) {
    echo $ex->getMessage();
  }
}

if ($msg <> "") { 
  echo "<center><h1>".$msg."</center></h1>"; 
  }
?>
</center>
</body>
</html>

The above file will get the ‘id’ of the user, decrypts it using intval() function, and then the record matching with the id is updated. (value of ‘verification’ filed is change to ‘verified’). You can see the updated value in database. If user again clicked on the activation button, the message appears “Your account has already been activated”.

Thanks for watching this tutorial. Please subscribe to our newsletter to catch such knowledgeable and useful tutorials.

Download Source Code

If you have any problems implementing above tutorial, please comment below. Alternatively, you can always download source code free of cost from below link.

12 thoughts on “User Registration with Email Verification in php

    1. E
      Ezenwa Hopekell says:

      Check if your local server is running, or if you have any server at all, if you don’t, get Xampp, Lamp or WAMP, and install on your PC

  1. Flexx says:

    Thanks for sharing this

    Very nice script but I get a error

    End well this error

    Connection failed: SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Name or service not known

    What can I do to fix this ??

      1. Flexx says:

        I have change a lot in the files so I don’t know where I must check it so I will start over again no big deal.

        Thanks for you fast reaply.

        If I have more questions I will let you know.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.