Key Takeaways
- This guide provides a step-by-step tutorial on how to create a social network style posting system using PHP, MongoDB, and jQuery. The final product will allow users to post status updates, like posts, and comment on posts.
- The guide is broken down into two parts. The first part focuses on designing the database architecture, stream, and application flow structure. The second part, covered in a separate article, will focus on the actual coding and implementation of the functionalities.
- The tutorial assumes that the reader has basic knowledge of PHP and MongoDB, but it is written in a newbie-friendly manner that can be adapted to other technologies.
- The guide also includes downloadable code for reference, although it is written in procedural form for simplicity and not as best practice. The post mechanism will be re-implemented in an object-oriented manner in a more complex guide in the future.
Post mechanisms similar to Facebook are nowadays very common within any application. The concept of Post-Like-Comment is familiar to everyone who ever used a social network. In this article, we will learn how to create a similar working model wherein the user will be able to post his status, like posts and comment on them. What’s more interesting is that after learning things from this article, going forward you will be able to implement a lot of other features on your own.
I’ll be using PHP as the coding language, MongoDB as the database and jQuery for JavaScript operations. It is assumed the reader is familiar with the basics of PHP and MongoDB to understand the article thoroughly. However, note that the article is written in a very generic and newbie-friendly manner and there is a lot to learn from it. So, even if you are not using Mongo DB or jQuery, you can easily adapt to or replace those technologies with those you prefer.
There are two articles in this series. In the first article, we will learn the database architecture, design the stream and think up the application flow structure that we are going to adapt. In the next article of this series, we will write the code which will eventually allow us to create a new post, like/unlike a post and comment on it. Understand that the first article is more of a base for the functionalities we are going to implement in the next part. As such, there will be cases where you will not understand the actual implementation logic of certain things until you find out more in the second article. The articles are accompanied by downloadable code for your reference. Please note that this code is written in procedural form and as such definitely not a best practice. This simplified form was chosen to make the implementation itself more newbie-friendly, and this post mechanism will be re-implemented in an object oriented manner in a more complex article down the line.
Before getting started, let us look at the final work we will develop (Fig 1 ).
Download Code:
Download the code provided with the article from its Github repo. You will find the following files in it:
index.php : This is the main file which displays all the posts and from where the user will interact.
mongo_connection.php : This file contains the common MongoDB connection code. If you have made any changes to the MongoDB connection credentials, you should specify them here. In all other PHP files, we will include this file to use the common MongoDB connection code. Make sure MongoDB is installed by following the installation instructions and installing the PHP drivers.
session_variables.php : The article expects that we have some common fields such as user id, user name and user’s profile picture stored in session variables as they are very frequently used throughout the application. Generally such information is set when the user logs in but for the purpose of the article, we will set it in this file.
script.js and style.css contains all the Javascript and CSS code. jquery.js is the standard jQuery library file.
php_scripts : This folder contains all the PHP files that we will call through AJAX to do PHP operations for inserting the post, performing like/unlike on the post and inserting comments.
images : This folder contains profile pictures of all the users.
Database Structure:
The users collection will be a simple one containing user id, user name and profile picture of the user as shown below:
{
"_id": ObjectId("5222f8e0d85242c01100000d"),
"name": "Richard Garry",
"profile_pic": "profile_pic_3.jpg"
}
Another collection posts_collection will maintain all the information related to posts as shown in the sample entry below:
{
"_id": ObjectId("5222f885d85242c011000009"),
"post_author_id": ObjectId("5146bb52d8524270060001f4"),
"post_text": "Let's get started !!!\t\t\t",
"timestamp": "Sun, 01-Sep-2013",
"total_comments": NumberInt(3),
"total_likes": NumberInt(2) ,
"likes_user_ids": {
"0": ObjectId("52147f70d85242cc12000010"),
"1": ObjectId("5222f8e0d85242c01100000d")
},
"comments": {
"0": {
"comment_id": ObjectId("5222f897d85242c01100000a"),
"comment_user_id": ObjectId("52147f70d85242cc12000010"),
"comment_text": "This is comment 1 !!"
},
"1": {
"comment_id": ObjectId("5222f8a7d85242c01100000b"),
"comment_user_id": ObjectId("5222f8e0d85242c01100000d"),
"comment_text": "This is comment 2 !!"
}
}
}
Most of the fields in the document are self-explanatory. likes_user_ids contains user ids of all the users who have liked the post. comments is an array which contains sub-documents to store the comments information.
Understanding Stream Design:
Let us first place a text area where the user will enter the post text and a button Create New Post (as shown in Fig 2 ) using the following code:
<div id="div_post_content">
<textarea id="post_textarea">
</textarea>
</div>
<div class="div_post_submit">
<input type="button" value="Create New Post" id="btn_new_post" class="button_style"/>
</div>
Our index page displays all the posts in a stream-like view. Looking at the code in index.php, we will explain how this data is fetched and displayed one step at a time:
We first fetch all the posts from the database and sort them with descending _id so as to get the last inserted posts first.
$posts_cursor=$collection->find()->sort(array('_id'=>-1));
Now, we iterate over all the fetched posts using foreach and get the post id, post text and user id of post author:
foreach($posts_cursor as $post)
{
$post_id=$post['_id'];
$post_text=$post['post_text'];
$post_author_id=$post['post_author_id'];
…
Using the user id, we can now get the user name and profile picture link from the users collection.
$collection = $database->selectCollection('users');
$post_author_details = $collection->findOne(array('_id' =>$post_author_id));
$post_author = $post_author_details['name'];
$post_author_profile_pic = $post_author_details['profile_pic'];
Understand that on our page, we will have many posts displayed together. Each post will have its Like button, like count, comments and comments count. We need to uniquely identify each of these things for each individual post so that when the user does any operation on any post (liking, commenting), we know which post to update. For this, we will initialize some variables which we will use as id of corresponding HTML elements later:
$post_like_unlike_id=$post_id.'_like_unlike';
$post_like_count_id=$post_id.'_like_count';
$post_comment_count_id = $post_id.'_comment_count';
$post_self_comment_id=$post_id.'_self_comment';
$post_comment_text_box_id=$post_id.'_comment_text_box';
We now check whether the current user has already liked the post or not. For this, we check if the user id of the current user is present in likes_user_ids array fetched from database. If the user has already liked the post, we set $like_or_unlike variable to display Unlike. But if the user has still not liked the post, we need to display Like option. We will use $like_or_unlike later in our HTML to display Like or Unlike option.
if(in_array($_SESSION['user_id'],$post['likes_user_ids']))
{
$like_or_unlike='Unlike';
}
else
{
$like_or_unlike='Like';
}
// you can also write this in short ternary form:
$like_or_unlike = (in_array($_SESSION['user_id'],$post['likes_user_ids'])) ? 'Unlike' : 'Like';
We will now use the variables initialized above and create the HTML structure to display the post. Each post_wrap
div will display one post and the id
of this post_wrap
will be the post id drawn from the database.
<div class="post_wrap" id="<?php echo $post['_id'];?>">
<div class="post_wrap_author_profile_picture">
<img src="images/<?php echo $post_author_profile_pic;?>" />
</div>
<div class="post_details">
<div class="post_author">
<?php echo $post_author ?>
</div>
<div class="post_text">
<?php echo $post_text; ?>
</div>
</div>
Now let’s show the number of likes and comments. Note that we had initialized some variables in the previous steps. Those variables are going to be used here. $like_or_unlike
displays the Like or Unlike text set earlier while $post_like_count_id
and $post_comment_count_id
are used to give ids of spans displaying the likes and comments count.
You will understand the use of assigning these ids in the next article, where we will have to get data and update it for each individual post.
<div class="comments_wrap">
<span>
<span><img src="images/like.png" /></span>
<span class="post_feedback_like_unlike" id="<?php echo $post_like_unlike_id;?>"><?php echo $like_or_unlike; ?></span>
<span class="post_feedback_count" id="<?php echo $post_like_count_id; ?>"><?php echo $post_like_count;?></span>
</span>
<span>
<span class="post_feedback_comment"> <img src="images/comment.png" /> Comment</span> <span class="post_feedback_count" id="<?php echo $post_comment_count_id; ?>"><?php echo $post_comment_count;?></span>
</span>
</div>
The above code would result in something like this (Fig 3):
Now, to show the comments related to each post, we iterate over the comments array retrieved from database and initialize variables to be used in HTML. For each comment, we perform a find query on the users collection to fetch the comment author’s name and profile picture link.
for($i=0;$i<$post_comment_count;$i++)
{
$comment_id=$post['comments'][$i]['comment_id'];
$comment_text=$post['comments'][$i]['comment_text'];
$comment_author_id=$post['comments'][$i]['comment_user_id'];
$collection = $database->selectCollection('users');
$comment_author_details = $collection->findOne(
array('_id' => new MongoId($comment_author_id))
);
$comment_author = $comment_author_details['name'];
$comment_author_profile_pic = $comment_author_details['profile_pic'];
Following is the HTML code to display a single comment using the variables initialized above: (Output: Fig 4)
<div class="comment" id="<?php echo $comment_id; ?>">
<div class="comment_author_profile_picture">
<img src="images/<?php echo $comment_author_profile_pic; ?>"/>
</div>
<div class="comment_details">
<div class="comment_author" >
<?php echo $comment_author; ?>
</div>
<div class="comment_text" >
<?php echo $comment_text; ?>
</div>
</div>
</div>
After displaying all the comments fetched form the database, we want to show a blank comment box wherein the current user can comment.
<div class="comment" id="<?php echo $post_self_comment_id; ?>">
<div class="comment_author_profile_picture">
<img src="images/<?php echo $_SESSION['user_profile_pic']; ?>" />
</div>
<div class="comment_text">
<textarea placeholder="Write a comment..." id="<?php echo $post_comment_text_box_id;?>" >
</textarea>
</div>
</div>
Application Flow Structure:
Let us now understand how the application flow will work by taking an example of inserting a new post. Don’t worry about the coding part for now as we are going to see that in the next article.
The first PHP file (
index.php
) is the main page from where the user will enter the post text and click on Create New Post button. For simplicity’s sake, we’ll put a JavaScript functionnew_post
as the click handler of this button and pass thepost_text
anduser_id
as its parameters.The JavaScript function will receive these parameters and send an AJAX POST request to a PHP file (
insert_new_post.php
) passing forward the same parameters it received.This PHP file does the work of inserting the received post text into the database. After doing the database operation, it prepares HTML content containing the new post which will be sent as output of the JavaScript function. This output will later be rendered on the main page. In reality, the PHP function should return JSON to reduce bandwidth, and the view file should just include the data into a prepared template, but seeing as our app is just a demonstration, this will do.
The JavaScript function receives the output sent by the PHP file and inserts it into the main page HTML.
The flow for all other operations (like commenting, liking/unliking post) is going to be similar to what we just saw for the example of inserting a post.
Conclusion:
In this article, we explained the database architecture, post stream design and application flow. In the next part of this series, we are going to use these structures and develop our functionality of inserting posts, like/unlike and commenting.
Frequently Asked Questions (FAQs) about PHP, MongoDB, and jQuery for Social Network Style Posting
What are the benefits of using PHP, MongoDB, and jQuery for social network style posting?
PHP, MongoDB, and jQuery are powerful tools for creating dynamic and interactive web applications. PHP is a server-side scripting language that is easy to learn and use. It is highly flexible and compatible with many databases, including MongoDB. MongoDB is a NoSQL database that provides high performance, high availability, and easy scalability. It works on the concept of collections and documents, making it easier to organize and manage data. jQuery is a fast, small, and feature-rich JavaScript library that simplifies HTML document traversing, event handling, and animating. It works across a multitude of browsers and is known for its simplicity and versatility. Together, these technologies can be used to create a robust and efficient social network style posting system.
How can I ensure the security of my PHP, MongoDB, and jQuery social network?
Security is a critical aspect of any web application. For PHP, you can use techniques like data sanitization, using prepared statements for SQL queries, and validating user input to prevent attacks. MongoDB provides built-in security features like authentication, authorization, and auditing. You can also encrypt your data at rest and in transit. For jQuery, ensure you’re using the latest version as it includes the most recent security patches. Also, be cautious when using third-party plugins and always validate user input.
Can I integrate other technologies with my PHP, MongoDB, and jQuery social network?
Yes, you can integrate other technologies with your PHP, MongoDB, and jQuery social network. For instance, you can use CSS and HTML for front-end design, AJAX for asynchronous data exchange between the server and the client, and APIs to integrate third-party services. The flexibility of these technologies allows for seamless integration with other tools and technologies.
How scalable is a social network built with PHP, MongoDB, and jQuery?
A social network built with PHP, MongoDB, and jQuery is highly scalable. PHP can handle a large number of requests, and MongoDB is designed for easy scalability with its sharding feature, which distributes data across multiple servers. jQuery, being a client-side technology, doesn’t impact server performance, making it suitable for scalable applications.
How can I optimize the performance of my PHP, MongoDB, and jQuery social network?
There are several ways to optimize the performance of your social network. For PHP, you can use opcode caches like APC or OPcache. For MongoDB, you can use indexing to speed up query performance, and sharding to distribute data and load. For jQuery, you can optimize performance by minimizing DOM manipulation, using AJAX wisely, and keeping selectors simple.
What are the best practices for error handling in PHP, MongoDB, and jQuery?
Error handling is crucial for maintaining the stability of your application. In PHP, you can use try-catch blocks to handle exceptions and error reporting for debugging. MongoDB provides comprehensive error messages that can help you diagnose and fix issues. In jQuery, you can use the .error() method to handle errors in AJAX requests.
How can I make my PHP, MongoDB, and jQuery social network mobile-friendly?
To make your social network mobile-friendly, you can use responsive web design techniques. This involves using flexible layouts, flexible images, and CSS media queries to ensure your website looks good on all devices. You can also use jQuery Mobile, a touch-optimized web framework for smartphones and tablets.
Can I use PHP, MongoDB, and jQuery to create a real-time social network?
Yes, you can use PHP, MongoDB, and jQuery to create a real-time social network. PHP can handle real-time data with the help of extensions like Ratchet and ReactPHP. MongoDB supports real-time data processing with its change streams feature. jQuery can handle real-time data with AJAX and WebSockets.
How can I test my PHP, MongoDB, and jQuery social network?
Testing is an essential part of the development process. For PHP, you can use tools like PHPUnit for unit testing. For MongoDB, you can use its inbuilt testing tools. For jQuery, you can use QUnit for unit testing and functional testing. You should also perform integration testing, performance testing, and security testing.
How can I debug my PHP, MongoDB, and jQuery social network?
Debugging is crucial for identifying and fixing issues in your application. For PHP, you can use Xdebug. For MongoDB, you can use its inbuilt diagnostic tools. For jQuery, you can use the browser’s developer tools. Always remember to log errors and exceptions for future reference.
Ashish is a Computer Science Engineer and works for one of the Big Four firms as a Technology Analyst. Prior to this, he co-founded an educational start-up. In his free time, Ashish read and write blogs, watches animation cartoons, movies or discovery channel. You can find his recent blogs on http://ashishtrivediblog.wordpress.com/