Demo Facebook like Button Application Using PHP, MySQL, jQuery and Ajax

Posted by & filed under Ajax, FACEBOOK, JAVASCRIPT, JQUERY, MYSQL, PHP.

This small demo application that demonstrates Live Facebook like Button Using PHP, MySQL, jQuery and Ajax. I will walk you through step by step making of this application. Please follow every step and finally you make it this demo appliaction yourself. If you completes this application you will come know HTML DOM updation using jQuery and some of Jquery ajax techniques.

Demo Facebook Like Button Application

Demo Facebook like button application using php mysql jquery and Ajax

Step 1:

Create new database in your MySQL database in the name of “facebook”, and now create following tables (posts, post_likes, users) using following SQL queries.

--
-- Database: `facebook`
--

-- --------------------------------------------------------
SET FOREIGN_KEY_CHECKS=0;
--
-- Table structure for table `posts`
--

CREATE TABLE `posts` (
  `id` int(11) NOT NULL,
  `image_link` text,
  `image_link_type` enum('full','relative') DEFAULT NULL,
  `description` longtext,
  `user_id` int(11) NOT NULL,
  `created_at` datetime DEFAULT NULL,
  `updated_at` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Dumping data for table `posts`
--

INSERT INTO `posts` (`id`, `image_link`, `image_link_type`, `description`, `user_id`, `created_at`, `updated_at`) VALUES
(1, 'image1.png', 'relative', NULL, 1, '2020-02-23 00:00:00', '2020-02-23 00:00:00'),
(2, 'image2.png', 'relative', NULL, 1, '2020-02-23 00:00:00', '2020-02-23 00:00:00'),
(3, 'image3.png', 'relative', NULL, 1, '2020-02-23 00:00:00', '2020-02-23 00:00:00'),
(4, 'image4.png', 'relative', NULL, 1, '2020-02-23 00:00:00', '2020-02-23 00:00:00'),
(5, 'https://images.unsplash.com/photo-1547036967-23d11aacaee0?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1203&q=80', 'full', NULL, 1, '2020-02-23 00:00:00', '2020-02-23 00:00:00'),
(6, 'https://images.unsplash.com/photo-1552055568-e9943cd2a08f?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2467&q=80', 'full', NULL, 1, '2020-02-23 00:00:00', '2020-02-23 00:00:00'),
(7, 'https://images.unsplash.com/photo-1557748859-969b8f5da1d5?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1275&q=80', 'full', NULL, 1, '2020-02-23 00:00:00', '2020-02-23 00:00:00'),
(8, 'https://images.unsplash.com/photo-1531096187418-86ac6b31baea?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2550&q=80', 'full', NULL, 1, '2020-02-23 00:00:00', '2020-02-23 00:00:00'),
(9, 'https://images.unsplash.com/photo-1554136310-2464e64fd97f?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1402&q=80', 'full', NULL, 1, '2020-02-23 00:00:00', '2020-02-23 00:00:00'),
(10, 'https://images.unsplash.com/photo-1514259912055-5e98a1591e7c?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1234&q=80', 'full', NULL, 1, '2020-02-23 00:00:00', '2020-02-23 00:00:00'),
(11, 'https://images.unsplash.com/photo-1528465258429-0c606ebeaad8?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2550&q=80', 'full', NULL, 1, '2020-02-23 00:00:00', '2020-02-23 00:00:00');

-- --------------------------------------------------------

--
-- Table structure for table `post_likes`
--

CREATE TABLE `post_likes` (
  `id` int(11) NOT NULL,
  `post_id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- Table structure for table `users`
--

CREATE TABLE `users` (
  `id` int(11) NOT NULL,
  `name` varchar(150) COLLATE utf8mb4_general_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

--
-- Dumping data for table `users`
--

INSERT INTO `users` (`id`, `name`) VALUES
(1, 'muni');

--
-- Indexes for dumped tables
--

--
-- Indexes for table `posts`
--
ALTER TABLE `posts`
  ADD PRIMARY KEY (`id`),
  ADD KEY `fk_posts_users_idx` (`user_id`);

--
-- Indexes for table `post_likes`
--
ALTER TABLE `post_likes`
  ADD PRIMARY KEY (`id`),
  ADD KEY `fk_post_likes_posts1_idx` (`post_id`),
  ADD KEY `fk_post_likes_users1_idx` (`user_id`);

--
-- Indexes for table `users`
--
ALTER TABLE `users`
  ADD PRIMARY KEY (`id`),
  ADD UNIQUE KEY `name` (`name`);

--
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT for table `posts`
--
ALTER TABLE `posts`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=12;

--
-- AUTO_INCREMENT for table `post_likes`
--
ALTER TABLE `post_likes`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;

--
-- AUTO_INCREMENT for table `users`
--
ALTER TABLE `users`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2;

--
-- Constraints for dumped tables
--

--
-- Constraints for table `posts`
--
ALTER TABLE `posts`
  ADD CONSTRAINT `fk_posts_users` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`);

--
-- Constraints for table `post_likes`
--
ALTER TABLE `post_likes`
  ADD CONSTRAINT `fk_post_likes_posts1` FOREIGN KEY (`post_id`) REFERENCES `posts` (`id`),
  ADD CONSTRAINT `fk_post_likes_users1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`);


SET FOREIGN_KEY_CHECKS=1;
COMMIT;

Here above tables relationship diagrams

Facebook-Like-Button-Demo-Using-php-mysql-jQuery

Step 2:

Create index.php file and add following scripts in it.

<?php
session_start();
if (!empty($_SESSION['name'])){
	header('Location: facebook.php');
}
?>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<!-- Bootstrap -->
		<link href="css/style.css" rel="stylesheet" media="screen">
		<title>Facebook like button Demo with Responsive Design</title>
	</head>
	<body class="login-page">
		<div class="container">
			<div class="login-form">
				<?php if (!empty($_SESSION["message"])) { ?>
					<p class="alert mb-2"><?= $_SESSION["message"] ?></p>
				<?php } ?>
				<h3 class="sub-title">
					Please Enter Your Name for Demo Purpose
				</h3>
				<hr>
				<form class="form-horizontal" role="form" id='login' action="facebook.php" method="post">
					<div class="form-group">
						<input type="text" class="form-control" id="name" name="name" placeholder="Enter your name">
						<span class="help-block"></span>
					</div>
					<div class="text-center">
						<button type="submit" class="btn btn-success btn-block">
							Primary
						</button>
					</div>
				</form>
			</div>
		</div>

		<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
		<script src="js/jquery-1.10.2.min.js"></script>
		<!-- Include all compiled plugins (below), or include individual files as needed -->
		<script src='//cdn.jsdelivr.net/npm/jquery-validation@1.19.1/dist/jquery.validate.min.js'></script>
		<script src="js/app.js"></script>
	</body>
</html>

It receives users name for demo purpose.

Step 2:

Create config.php to maintain Database connection in single file.

<?php
/**
 * File config.php
 * @author muni
 * @link https://smarttutorials.net/
 */

define('DB_HOST', 'localhost');
define('DB_NAME', 'facebook');
define('DB_USER','xyz');
define('DB_PASSWORD','mysql');

$mysqli = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);

if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: " . $mysqli -> connect_error;
    exit();
}

/**
 * Preparing Statement
 */
function prepareStatement($sql, $params = null)
{
    global $mysqli;
    $stmt = $mysqli->prepare($sql);
    if (!($stmt)) {
        throw new Exception("Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error);
    }

    if (!empty($params) && is_array($params)) {
        $count = count($params);            
        $bindStr = str_repeat('s', $count);
        $stmt->bind_param($bindStr, ...$params);
    }

    if (!$stmt->execute()) {
        throw new Exception("Execute failed: (" . $stmt->errno . ") " . $stmt->error);
    }

    return $stmt;
}

/**
 * GetResult
 */
function getResult($stmt)
{
    if (!($res = $stmt->get_result())) {
        throw new Exception("Getting result set failed: (" . $stmt->errno . ") " . $stmt->error);
    }
    return $res;
}

Step 3:

Now create facebook.php file and add the following scripts in it.

<?php
require_once 'config.php';
session_start();
require_once 'functions.php';

try {
	if (!empty($_POST['name'])) {
		addNewUser($_POST);
	}

	if(empty($_SESSION['name'])){
		$_SESSION["message"] = "You are not logged-in, Please login to continue";
		header('Location: index.php');
	}

	$posts = getPostLikes();
} catch (Exception $e) {
	//$e
}
?>
<!DOCTYPE html>
<html class="no-js">
	<head>
		<meta charset="UTF-8">
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<title>Facebook like button Demo with Responsive Design</title>
		<link href="css/font-awesome.min.css" rel="stylesheet" media="screen">
		<link href="css/font-awesome-ie7.min.css" rel="stylesheet" media="screen">
		<link href="css/style.css" rel="stylesheet" media="screen">
	</head>
	<body>
		<div class="container">
			<h1 class="title text-center">Facebook Like Button Demo with Responsive Design</h1>
			<hr class="mb-2">
			<div class="text-center">
				<p> You are loggedin as <strong class="ft-1 underline"><?= $_SESSION['name'] ?></strong></p>
			</div>
			<div class="image_outer_container">
				
				<?php 
				foreach ($posts as $key => $result) {       
				?>
				<div class="image_container">

					<?php
						$img_url  = $result['image_link_type'] == 'relative' 
						? 'image/'.$result['image_link'] : $result['image_link'];
					?>

					
					<img data-src='<?php echo $img_url ; ?>' loading="lazy" class="img-responsive lazyload"/>




					<p id="like_container<?php echo $result['id']; ?>" class='like_container'>
						<a id="<?php echo $result['id']; ?>" class="btn like" href="javascript:;"> <i class="icon-hand-up"></i> <span class="dis"> Like Me!!</span></a><span class="score"><?php echo $result['likesCount']; ?></span>people like this
					</p>
				</div>
				<?php } ?>
                <input id="name" type='hidden' value="<?php echo $_SESSION['name']; ?>"/>
                <input id="id" type='hidden' value="<?php echo $_SESSION['id']; ?>"/>
			</div>
		</div>
		
		<footer>	    
			<p class="text-center" id="foot">&copy;<a href="https://smarttutorials.net/" target="_blank"> Smart Tutorials </a> <?php echo date('Y') ?></p>
		</footer>
		
		<div class="loader"></div>

		
		<script src="js/jquery-1.10.2.min.js"></script>
		<script src="js/app.js"></script>
	</body>
</html>

Step 4:

Create style.css file and add following css styles in it.

@import url('https://fonts.googleapis.com/css?family=Raleway:400,700&display=swap');
*{
	margin: 0px;
	padding: 0px;
	box-sizing: border-box;
}
body {
	background:#42D39B;
	color:#fff;
	position: relative;
	font-family: Raleway, sans-serif;
	font-size: 16px;
	font-weight: 400;
}
.text-center{
	text-align: center;
}
footer{background:#E26A6A;height:80px;padding-top:20px;}
.loader {
	position: fixed;
	left: 0px;
	top: 0px;
	width: 100%;
	height: 100%;
	z-index: 9999;
	background: url(../image/loader.gif) 50% 50% no-repeat rgb(249,249,249);
}
html, body{
	height: 100%;
	width: 100%;
}
.login-page .container{
	height: 100%;
	width: 100%;
	display: flex;
	align-items: center;
    justify-content: center;
}
.login-form{
	width: 300px;
	margin: 0px 15px;
	text-align: center;
}
.form-group{
	display: block;
	width: 100%;
	margin: 15px 0px;
}
.form-control {
	display: block;
    width: 100%;
    height: calc(1.5em + .75rem + 2px);
    padding: .375rem .75rem;
    font-size: 1rem;
    font-weight: 400;
    line-height: 1.5;
    color: #495057;
    background-color: #fff;
    background-clip: padding-box;
    border: 1px solid #ced4da;
    border-radius: .25rem;
    transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out;
}
.btn {
    display: inline-block;
    font-weight: 400;
    color: #212529;
    text-align: center;
    vertical-align: middle;
    cursor: pointer;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    background-color: transparent;
    border: 1px solid transparent;
    padding: .375rem .75rem;
    font-size: 1rem;
    line-height: 1.5;
    border-radius: .25rem;
    transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;
}
.btn-success {
    color: #fff;
    background-color: #28a745;
    border-color: #28a745;
}
.btn-info {
    color: #fff;
    background-color: #04a9ff;
    border-color: #04a9ff;
}
.help-block{
	display: inline-block;
	font-size: .9rem;
}
.form-group.has-error .help-block{
	color: #ff2424;
}
.form-group.has-success .help-block{
	color: #095236;
}
input, select, textarea{
	font-family: inherit;
}
.sub-title{
	font-weight: 400;
}

.container{
	width: calc(100% - 30px);
	margin: 15px;
	max-width: 1200px;
	margin: 0px auto;
}
.title{
	font-size: 2rem;
	font-weight: 400;
	margin-top: 50px;
}
.mb-2{
	margin-bottom: 2rem;
}
.img-responsive{
	width: 100%;
}
.image_outer_container{
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	flex: 1 1;
}
.image_container{
	display: flex;
	flex-direction: column;
	width: 300px;
	margin: 15px;
	flex-wrap: wrap;
	justify-content: center;
}
.like_container {
    text-align: center;
    padding: 10px;
}
span.score {
    padding: 5px;
    font-size: 20px;
	font-weight: 700;
}

.alert{
	background-color: brown;
    padding: 5px;
}
.underline{
	text-decoration: underline;
}
.ft-1{
	font-size: 1.5rem;
}



@media only screen and (min-width: 500px) {
	.login-form{
		width: 400px;
	}	
	
	.image_container{
		width: 500px;
	}
}

Step 5:
Next create functions.php file to keep functions to add new user, Get Likes count, Check User Exists and etc…

<?php
/**
 * File functions.php
 * @author muni
 * @link https://smarttutorials.net/
 */


function addNewUser($data)
{
    global $mysqli;
    $name = $data['name'];
    $userId = checkUserExists($name);
    if (!$userId) {
        $sql = "INSERT INTO users (id, name)VALUES (NULL, ?)";
        prepareStatement($sql, [$name]);
        $userId = $mysqli ->insert_id;
    } 
    $_SESSION['name']= $name;
    $_SESSION['id'] = $userId;
}

function checkUserExists($name)
{
    $sql = "select id from users where name=?"; 
    $stmt = prepareStatement($sql, [$name]);
    $res = getResult($stmt);
    $result =  $res->fetch_assoc();
    return $result['id'] ? $result['id'] : 0;
}

function checkUserAlreadyPost($post_id, $user_id)
{
    $sql = "select id from post_likes where post_id=? and user_id=?";
    $stmt = prepareStatement($sql, [$post_id, $user_id]);
    $res = getResult($stmt);
    return $res->num_rows;
}

function getPostLikeCount($post_id)
{
    $sql = "select count(post_id) as count from post_likes where post_id=?"; 
    $stmt = prepareStatement($sql, [$post_id]);
    $res = getResult($stmt);
    $result =  $res->fetch_assoc();
    return $result['count'] ? $result['count'] : 0;
}

function likePost($post_id, $user_id)
{
    global $mysqli;
    $sql = "INSERT INTO post_likes (id, post_id,user_id) VALUES (NULL,?,?)";
    prepareStatement($sql, [$post_id, $user_id]);
    return getPostLikeCount($post_id);
}


function dislikePost($post_id, $user_id)
{
    $sql = "DELETE FROM post_likes where post_id = ? and user_id = ?";
    prepareStatement($sql, [$post_id, $user_id]);
    return getPostLikeCount($post_id);  
}

function getPostLikes()
{
    $sql = "SELECT Posts.id, Posts.image_link, Posts.image_link_type, 
        Posts.description, Posts.user_id,
        count(post_id) as likesCount FROM `posts` Posts 
        LEFT JOIN post_likes PostLikes 
        ON PostLikes.post_id = Posts.id
        GROUP BY Posts.id
        order by Posts.id ASC";
    $stmt = prepareStatement($sql);
    $res = getResult($stmt);
    return $res->fetch_all(MYSQLI_ASSOC);
}

Step 6:
Finally create check_name.php file which handles all the ajax request from  other PHP files.

<?php
require_once 'config.php';
require_once 'functions.php';
try {
    if (!empty($_POST['name'])) {
        $name=$_POST['name'];
        $sql = "SELECT name FROM users where name = ?";
        $stmt = prepareStatement($sql, [$name]);
        $res =  getResult($stmt);
        $row_cnt = $res->num_rows;

        if ($row_cnt ==0) {
            echo 'true';
        } else{
            echo 'false';
        }
        exit;
    }

    if (isset($_POST['flag'])) {
        $like_id = $_POST['id'];
        $user_id = $_POST['user_id'];
        echo checkUserAlreadyPost($like_id, $user_id);
        exit;
    }

    if(isset($_POST['flag1'])){
        $like_id=$_POST['id'];
        $user_id=$_POST['user_id'];
        $count = checkUserAlreadyPost($like_id, $user_id);

        if ($count==0) {
            echo likePost($like_id, $user_id); 
        } else {
            echo dislikePost($like_id, $user_id);  
        }
        exit;
    }

} catch (Exception $e) {
    echo $e->getMessage();
    exit;
}

Step 7:
All DOM manipulation and jQuery related functionalities are kept app.js file.

$(window).load(function() {
    $(".loader").fadeOut("slow");
});

$(document).ready(function(){
    $(".loader").fadeOut("slow");

    if ('loading' in HTMLImageElement.prototype) {
        var images = document.querySelectorAll("img.lazyload");
        images.forEach(img => {
            img.src = img.dataset.src;
        });
    } else {
        // Dynamically import the LazySizes library
        let script = document.createElement("script");
        script.async = true;
        script.src =
        "https://cdnjs.cloudflare.com/ajax/libs/lazysizes/4.1.8/lazysizes.min.js";
        document.body.appendChild(script);
    }
});

$(document).on('mouseenter', '.like', function() {
    id = $(this).attr('id');
    name = $('#name').val();
    user_id = $('#id').val();
    container = $(this).closest('.like_container').attr('id');
    $.ajax({
        type : "POST",
        url : "check_name.php",
        data : {
            id : id,
            user_id : user_id,
            flag : 'check_unique'
        },
        async : false,
        success : function(data) {
            data = parseInt(data);
            if (data > 0) {
                $('#' + container).find('i').removeClass('icon-hand-up').addClass('icon-hand-down');
                $('#' + container).find('.dis').html('Unlike Me!!');
            }
        }
    });

    $('#' + id).mouseleave(function() {
        $('#' + container).find('i').removeClass('icon-hand-down').addClass('icon-hand-up');
        $('#' + container).find('.dis').html('Like Me!!');
    });
});

$(document).on('click', '.like', function() {
    id = $(this).attr('id');
    user_id = $('#id').val();
    container = $(this).closest('.like_container').attr('id');
    $.ajax({
        type : "POST",
        url : "check_name.php",
        data : {
            id : id,
            user_id : user_id,
            flag1 : 'update'
        },
        async : false,
        success : function(data) {
            $('#' + container).find('.score').html(data);
        }
    });
});

/**
 * Index Page JS
 */
if ($("#login").validate) {
    $("#login").validate({
        submitHandler: function(form) {
            form.submit();
        },
        rules : {
            name : {
                required : true,
                minlength : 3,
                remote : {
                    url : "check_name.php",
                    type : "post",
                    data : {
                        username : function() {
                            return $("#name").val();
                        }
                    }
                }
            }
        },
        messages : {
            name : {
                required : "Please enter your name",
                remote : function(){
                    $('#name').rules('remove', 'remote');
                    $("#login").submit();
                    return true;
                    
                    //return "Name is already taken, Please choose some other name"
                }
            }
        },
        errorPlacement : function(error, element) {
            $(element).closest('.form-group').find('.help-block').html(error.html());
        },
        highlight : function(element) {
            $(element).closest('.form-group').removeClass('has-success').addClass('has-error');
        },
        success : function(element, lab) {
            var messages = new Array("That's Great!", "Looks good!", "You got it!", "Great Job!", "Smart!", "That's it!");
            var num = Math.floor(Math.random() * 6);
            $(lab).closest('.form-group').find('.help-block').text(messages[num]);
            $(lab).addClass('valid').closest('.form-group').removeClass('has-error').addClass('has-success');
        }
    });
}    

Download Premium Only Scripts & 80+ Demo scripts Instantly at just 1.95 USD per month + 10% discount to all Exclusive Scripts

If you want any of my script need to be customized according to your business requirement,

Please feel free to contact me [at] muni2explore[at]gmail.com

Note: But it will be charged based on your customization requirement

Get Updates, Scripts & Other Useful Resources to your Email

Join 10,000+ Happy Subscribers on feedburner. Click to Subscribe (We don't send spam)
Every Email Subsciber could have access to download 100+ demo scripts & all future scripts.

Get Instant Script Download Access!