Email Subscription System with PHP & MySQL

Email Subscription is implemented into websites to allow visitors to register their email to get daily, weekly or monthly update from subscribed website. There are beautiful user friendly subscription form created to enter Email address and name to subscribe.

So if you’re developing a project or wants to implement email subscription functionality to your existing website, then it’s vey easy. In our previous tutorial you have learned how to develop content management system with PHP and MySQL. In this tutorial, you will learn how to implement Email Subscription with Ajax, PHP and MySQL.

Also, read:

We will cover this tutorial with live example. We will cover following features in our email subscription example.


  • User will submit email subscription form with name and email address.
  • Check for existing email address and display message if it is already subscribed.
  • Email verification send to user email address with very email link.
  • User click on email confirmation link and verified and subscribed.

Now let’s proceed to develop the email subscription. We will have following file structure for this project.

  • email-subscription-system-php-mysql-demo
    • config
      • Database.php
    • class
      • Subscription
    • js
      • ajax_subscribe.js
    • css
      • style.css
    • index.php
    • susbcribe_action.php
    • verify_email.php

Step1: Create MySQL Database Table

First we will create MySQL database table subscription to store subscribers details.

CREATE TABLE `subscription` (
  `id` int(11) NOT NULL,
  `name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  `email` varchar(200) COLLATE utf8_unicode_ci NOT NULL,
  `verify_token` varchar(150) COLLATE utf8_unicode_ci DEFAULT NULL,
  `is_verified` tinyint(1) NOT NULL DEFAULT 0,
  `created` datetime NOT NULL,
  `modified` datetime NOT NULL DEFAULT current_timestamp(),
  `status` tinyint(1) NOT NULL DEFAULT 1
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Step2: Create Subscription Form

We will create email subscription form in index.php with name and email input.

<div class="row">
	<div class="col-lg-12">
		<div class="main-content">
			<div class="susbcribe-container">
				<div class="top">
					<h2>Subscribe Now</h2>													
				</div>
				<div class="bottom">							
					<div class="status"></div>						
					<form action="#" id="subscribeForm" method="post">							
						<input type="text" class="form-control" id="name" placeholder="Full Name" required="">	
						<span class="text-danger hidden" id="nameError"></span>
						<input type="email" class="form-control" id="email" placeholder="E-mail" required="">
						<span class="text-danger hidden" id="emailError"></span>
						<input type="button" id="subscribeButton" value="Subscribe Now">
					</form>
				</div>
			</div>
		</div>
	</div>
</div>

Step3: Handle Subscription Form Submit

In ajax_susbscribe.js file, we will handle subscription form submit and make ajax request to subscribe_action.php with action email_subscribe to handle email subscription functionality at the server side.

$('#subscribeButton').on('click', function() {        
	$('.status').html('');        
	var regEmail = /^[A-Z0-9._%+-]+@([A-Z0-9-]+\.)+[A-Z]{2,4}$/i;
	var name = $('#name').val();
	var email = $('#email').val();	        
	if(name.trim() == '' ) {           
		$('#nameError').text('Please enter name.').removeClass('hidden');
		$('#emailError').text('').addClass('hidden');
		$('#name').focus();
		return false;
	} else if(email.trim() == '' ) {          
		$('#emailError').text('Please enter email.').removeClass('hidden');
		$('#nameError').text('').addClass('hidden');
		$('#email').focus();
		return false;
	} else if(email.trim() != '' && !regEmail.test(email)) {          
		$('#emailError').text('Please enter a valid email.').removeClass('hidden');
		$('#nameError').text('').addClass('hidden');
		$('#email').focus();
		return false;
	} else {            
		$.ajax({
			type:'POST',
			url:'subscribe_action.php',
			dataType: "json",
			data:{email_subscribe:1, name:name, email:email},
			beforeSend: function () {
				$('#subscribeButton').attr("disabled", "disabled");
				$('.susbcribe-container').css('opacity', '.5');
			},
			success:function(data) {
				if(data.status == 'ok') {
					$('#subscribeForm')[0].reset();
					$('.status').html('<p class="success">'+data.msg+'</p>');
				} else {
					$('.status').html('<p class="error">'+data.msg+'</p>');
				}
				$('#subscribeButton').removeAttr("disabled");
				$('.susbcribe-container').css('opacity', '');
			}
		});
	}
});	 

Step4: Handle Email Subscription

In subscribe_action.php file, we will handle email subscription functionality to check for email subscription already exist or save new subscription. We will design email content and send email with token to verify email address.


if(isset($_POST['email_subscribe'])){ 
    $errorMsg = '';     
    $response = array( 
        'status' => 'err', 
        'msg' => 'Something went wrong, please try after some time.' 
    );     
    
    if(empty($_POST['name'])){ 
        $pre = !empty($msg)?'<br/>':''; 
        $errorMsg .= $pre.'Please enter your full name.'; 
    } 
	
    if(empty($_POST['email']) && !filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)){ 
        $pre = !empty($msg)?'<br/>':''; 
        $errorMsg .= $pre.'Please enter a valid email.'; 
    } 
         
    if(empty($errorMsg)){ 
        $name = $_POST['name']; 
        $email = $_POST['email']; 
        $token = md5(uniqid(mt_rand()));  
               
		$subscriber->email = $email;
        if($subscriber->getSusbscriber()){ 
            $response['msg'] = 'Your email already exists in our subscribers list.'; 
        } else {      
			
			$subscriber->name = $name;
			$subscriber->verify_token = $token;
			$insert = $subscriber->insert(); 
             
            if($insert){ 
			
				$siteName = 'PHPZAG Site'; 
				$siteEmail = 'abc@phpzag.com'; 
				 
				$siteURL = ($_SERVER["HTTPS"] == "on")?'https://':'http://'; 
				$siteURL = $siteURL.$_SERVER["SERVER_NAME"].dirname($_SERVER['REQUEST_URI']).'/';
			
                $verifyLink = $siteURL.'verify_email.php?email_verify='.$token; 
                $subject = 'Confirm Subscription'; 
     
                $message = '<h1 style="font-size:22px;margin:18px 0 0;
				padding:0;text-align:left;color:#3c7bb6">Email Confirmation</h1> 
                <p style="color:#616471;text-align:left;padding-top:15px;
				padding-right:40px;padding-bottom:30px;padding-left:40px;font-size:15px">
				Thank you for signing up 
				with '.$siteName.'! Please confirm your email address 
				by clicking the link below.</p> 
                <p style="text-align:center;"> 
                    <a href="'.$verifyLink.'" style="border-radius:.25em;
					background-color:#4582e8;
					font-weight:400;min-width:180px;font-size:16px;
					line-height:100%;padding-top:18px;
					padding-right:30px;padding-bottom:18px;padding-left:30px;
					color:#fffffftext-decoration:none">Confirm Email</a> 
                </p> 
                <br><p><
				strong>'.$siteName.' Team</strong></p>'; 
                 
                $headers = "MIME-Version: 1.0" . "\r\n";  
                $headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";  
                $headers .= "From: $siteName"." <".$siteEmail.">"; 
                 
                $mail = mail($email, $subject, $message, $headers); 
                if($mail){ 
                    $response = array( 
                        'status' => 'ok', 
                        'msg' => 'A verification link has been 
						sent to your email address, please check your email and verify.' 
                    ); 
                } 
            } 
        } 
    } else { 
        $response['msg'] = $errorMsg; 
    }       
    echo json_encode($response); 
} 

We will implement method insert() in class Subscription.php to insert the subscriber details into database table.

public function insert(){
		
	if($this->name && $this->email && $this->verify_token) {

		$stmt = $this->conn->prepare("
		INSERT INTO ".$this->subscribeTable."(`name`, `email`, `verify_token`)
		VALUES(?,?,?)");
	
		$this->name = htmlspecialchars(strip_tags($this->name));
		$this->email = htmlspecialchars(strip_tags($this->email));
		$this->verify_token = htmlspecialchars(strip_tags($this->verify_token));					
		
		$stmt->bind_param("sss", $this->name, $this->email, $this->verify_token);
		
		if($stmt->execute()){
			return true;
		}		
	}
}

Step5: Verify Subscription Email

In verify_email.php file, we will check for email_verify and handle email verification functionality. Check for valid verification token and update the subscription verify details.

$verifyMessage = '';
if(!empty($_GET['email_verify'])){     
	$token = $_GET['email_verify']; 	
	$subscriber->verify_token = $token;
    if($subscriber->isValidToken()){ 
       	$subscriber->is_verified = 1;        
        if($subscriber->update()) { 
            $verifyMessage = '<p class="success">Your email 
			address has been verified successfully.</p>'; 
        } else { 
            $verifyMessage = '<p class="error">Some problem 
			occurred on verifying your email, please try again.</p>'; 
        } 
    } else { 
        $verifyMessage = '<p class="error">You have clicked on 
		the wrong link, please check your email and try again.</p>'; 
	}
}

We will implement the update() method in class Subscription.php to update the subscriber details.

public function update(){
	
	if($this->verify_token) {			
		
		$stmt = $this->conn->prepare("
		UPDATE ".$this->subscribeTable." 
		SET is_verified= ? WHERE verify_token = ?");
 
		$this->verify_token = htmlspecialchars(strip_tags($this->verify_token));
				
		$stmt->bind_param("is", $this->is_verified, $this->verify_token);
		
		if($stmt->execute()){
			return true;
		}
		
	}	
}

You may also like:

You can view the live demo from the Demo link and can download the script from the Download link below.
Demo Download


2 thoughts on “Email Subscription System with PHP & MySQL

  1. I solved the previous one
    I got this and I am struggling
    any help plz

    Fatal error: Uncaught Error: Call to a member function bind_param() on bool in C:\xampp\htdocs\php\ecom\class\Subscription.php:23
    Stack trace:
    #0 C:\xampp\htdocs\php\ecom\subscribe_action.php(39): Subscription->insert()
    #1 {main}
    thrown in C:\xampp\htdocs\php\ecom\class\Subscription.php on line 23

Comments are closed.