HTML CSS JavaScript jQuery PHP Python MySQL

Review System with PHP, MySQL, and AJAX

Updated on by David Adams

Review System with PHP, MySQL, and AJAX

In this tutorial we'll be creating a review system with PHP, MySQL, and AJAX (JavaScript). With the review system, your users can share their own opinion and experiences that relate to your services, products, etc.

We'll be able to implement the review system to any webpage, even a static HTML document. How is this possible? We're going to use AJAX to fetch results from our PHP server, which will be determined by the webpage the user is currently on.

You'll be able to implement this review system into your website hassle-free, as long as you have PHP and MySQL installed.

The Advanced package includes additional features and a download link to the source code.

1. Getting Started

If you want to install the review system on your local environment, you'll need to install a webserver solution. Follow the below instructions.

  • Install a webserver solution package such as XAMPP.
  • If you have your own server (VPS, Dedicated, etc), you'll need to install PHP, Apache, MySQL, and phpMyAdmin (Note: these are already included with XAMPP).
  • Install a code editor. You can use Notepad, but I don't recommend it. Install one of the following instead: Notepad++, Visual Studio Code, or Atom.

2. Creating the Database and setting-up Tables

Now we need to create the MySQL database and create the reviews table, which we can do with phpMyAdmin.

Navigate to phpMyAdmin (e.g. http://localhost/phpmyadmin/) in your browser and follow the below instructions:

  • Click the Databases tab at the top
  • Under Create database, type in phpreviews in the text box
  • Select utf8_general_ci as the collation (UTF-8 is the default encoding in HTML5)
  • Click Create

While the database is selected, click the SQL tab and execute the following SQL statement:

SQL Copy
CREATE TABLE IF NOT EXISTS `reviews` (
	`id` int(11) NOT NULL AUTO_INCREMENT,
	`page_id` int(11) NOT NULL,
	`name` varchar(255) NOT NULL,
	`content` text NOT NULL,
	`rating` tinyint(1) NOT NULL,
	`submit_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
	PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8;

INSERT INTO `reviews` (`id`, `page_id`, `name`, `content`, `rating`, `submit_date`) VALUES
(1, 1, 'David Deacon', 'I use this website daily, the amount of content is brilliant.', 5, '2020-01-09 20:43:02'),
(2, 1, 'John Doe', 'Great website, great content, and great support!', 4, '2020-01-09 21:00:41'),
(3, 1, 'Robert Billings', 'Website needs more content, good website but content is lacking.', 3, '2020-01-09 21:10:16'),
(4, 1, 'Daniel Callaghan', 'Great!', 5, '2020-01-09 23:51:05'),
(5, 1, 'Bobby', 'Not much content.', 2, '2020-01-14 21:54:24'),
(6, 1, 'Joshua Kennedy', 'Fantasic website, has everything I need to know.', 5, '2020-01-16 17:34:27'),
(7, 1, 'Johannes Hansen', 'Really like this website, helps me out a lot!', 5, '2020-01-16 17:35:12'),
(8, 1, 'Wit Kwiatkowski', 'Please provide more quality content.', 5, '2020-01-16 17:36:03'),
(9, 1, 'Óli Þórðarson', 'Thanks', 5, '2020-01-16 17:36:34'),
(10, 1, 'Jaroslava Beránková', '', 5, '2020-01-16 17:37:48'),
(11, 1, 'Naomi Holt', 'Appreciate the amount of content you guys do.', 5, '2020-01-16 17:39:17'),
(12, 1, 'Isobel Whitehead', 'Thank you for providing a website that helps us out a lot!', 5, '2020-01-16 17:40:28'),
(13, 1, 'Warren Mills', 'Everything is awesome!', 5, '2020-01-16 19:34:08'),
(14, 1, 'Larry Johnson', 'Brilliant, thank you for providing quality content!', 5, '2020-01-29 18:40:36');

The data that we insert into the reviews table will be for testing purposes.

The above SQL statement will create the reviews table with the following columns:

  • id — The unique review ID.
  • page_id — This will determine which review is for which page. It will be the page ID that you can specify on any webpage.
  • name — The name of the user (e.g. Joe Bloggs).
  • content — The review content that the user will submit via the form.
  • rating — The review rating that will be from 1 to 5.
  • submit_date — The date the review was posted.

On phpMyAdmin this should look like:

http://localhost/phpmyadmin/
MySQL Reviews Table

3. Creating the Stylesheets (CSS3)

We'll be creating two stylesheets for our review system, one will be for our home page, which will be used as an example of how we'll implement the review system, and the other stylesheet will be used for the review system.

Stylesheets are used to format the layout of our review system.

Create the style.css file and add:

CSS Copy
* {
    box-sizing: border-box;
    font-family: -apple-system, BlinkMacSystemFont, "segoe ui", roboto, oxygen, ubuntu, cantarell, "fira sans", "droid sans", "helvetica neue", Arial, sans-serif;
    font-size: 16px;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}
body {
    background-color: #FFFFFF;
    margin: 0;
}
.navtop {
    background-color: #3f69a8;
    height: 60px;
    width: 100%;
    border: 0;
}
.navtop div {
    display: flex;
    margin: 0 auto;
    width: 1000px;
    height: 100%;
}
.navtop div h1, .navtop div a {
    display: inline-flex;
    align-items: center;
}
.navtop div h1 {
    flex: 1;
    font-size: 24px;
    padding: 0;
    margin: 0;
    color: #ecf0f6;
    font-weight: normal;
}
.navtop div a {
    padding: 0 20px;
    text-decoration: none;
    color: #c5d2e5;
    font-weight: bold;
}
.navtop div a i {
    padding: 2px 8px 0 0;
}
.navtop div a:hover {
    color: #ecf0f6;
}
.content {
    width: 1000px;
    margin: 0 auto;
}
.content h2 {
    margin: 0;
    padding: 25px 0;
    font-size: 22px;
    border-bottom: 1px solid #ebebeb;
    color: #666666;
}

Create the reviews.css file and add:

CSS Copy
.reviews .overall_rating .num {
    font-size: 30px;
    font-weight: bold;
    color: #F5A624;
}
.reviews .overall_rating .stars {
    letter-spacing: 3px;
    font-size: 32px;
    color: #F5A624;
    padding: 0 5px 0 10px;
}
.reviews .overall_rating .total {
    color: #777777;
    font-size: 14px;
}
.reviews .write_review_btn, .reviews .write_review button {
    display: inline-block;
    background-color: #565656;
    color: #fff;
    text-decoration: none;
    margin: 10px 0 0 0;
    padding: 5px 10px;
    border-radius: 5px;
    font-size: 14px;
    font-weight: 600;
    border: 0;
}
.reviews .write_review_btn:hover, .reviews .write_review button:hover {
    background-color: #636363;
}
.reviews .write_review {
    display: none;
    padding: 20px 0 10px 0;
}
.reviews .write_review textarea {
    width: 100%;
    padding: 10px;
    border: 1px solid #ddd;
    border-radius: 5px;
    height: 150px;
    margin-top: 10px;
}
.reviews .write_review input {
    display: block;
    width: 250px;
    padding: 10px;
    border: 1px solid #ddd;
    border-radius: 5px;
    margin-top: 10px;
}
.reviews .write_review button {
    cursor: pointer;
}
.reviews .review {
    padding: 20px 0;
    border-bottom: 1px solid #eee;
}
.reviews .review .name {
    padding: 0 0 3px 0;
    margin: 0;
    font-size: 18px;
    color: #555555;
}
.reviews .review .rating {
    letter-spacing: 2px;
    font-size: 22px;
    color: #F5A624;
}
.reviews .review .date {
    color: #777777;
    font-size: 14px;
}
.reviews .review .content {
    padding: 5px 0;
}
.reviews .review:last-child {
    border-bottom: 0;
}

4. Creating the Review System with PHP

We can now start coding our review system with PHP. The script we're going to implement will retrieve results from our database and populate the output in HTML format.

Create the reviews.php file and add:

PHP Copy
<?php
// Update the details below with your MySQL details
$DATABASE_HOST = 'localhost';
$DATABASE_USER = 'root';
$DATABASE_PASS = '';
$DATABASE_NAME = 'phpreviews';
try {
    $pdo = new PDO('mysql:host=' . $DATABASE_HOST . ';dbname=' . $DATABASE_NAME . ';charset=utf8', $DATABASE_USER, $DATABASE_PASS);
} catch (PDOException $exception) {
    // If there is an error with the connection, stop the script and display the error.
    exit('Failed to connect to database!');
}

The code above will connect to our MySQL database (phpreviews). The database variables must reflect your MySQL credentials or else you will encounter an error.

Add after:

PHP Copy
// Below function will convert datetime to time elapsed string.
function time_elapsed_string($datetime, $full = false) {
    $now = new DateTime;
    $ago = new DateTime($datetime);
    $diff = $now->diff($ago);
    $diff->w = floor($diff->d / 7);
    $diff->d -= $diff->w * 7;
    $string = array('y' => 'year', 'm' => 'month', 'w' => 'week', 'd' => 'day', 'h' => 'hour', 'i' => 'minute', 's' => 'second');
    foreach ($string as $k => &$v) {
        if ($diff->$k) {
            $v = $diff->$k . ' ' . $v . ($diff->$k > 1 ? 's' : '');
        } else {
            unset($string[$k]);
        }
    }
    if (!$full) $string = array_slice($string, 0, 1);
    return $string ? implode(', ', $string) . ' ago' : 'just now';
}

The above function will be used to format the review date, for example, the date "2020-01-09 20:43:02" will be converted to "3 weeks ago".

Add after:

PHP Copy
// Page ID needs to exist, this is used to determine which reviews are for which page.
if (isset($_GET['page_id'])) {
    if (isset($_POST['name'], $_POST['rating'], $_POST['content'])) {
        // Insert a new review (user submitted form)
        $stmt = $pdo->prepare('INSERT INTO reviews (page_id, name, content, rating, submit_date) VALUES (?,?,?,?,NOW())');
        $stmt->execute([$_GET['page_id'], $_POST['name'], $_POST['content'], $_POST['rating']]);
        exit('Your review has been submitted!');
    }
    // Get all reviews by the Page ID ordered by the submit date
    $stmt = $pdo->prepare('SELECT * FROM reviews WHERE page_id = ? ORDER BY submit_date DESC');
    $stmt->execute([$_GET['page_id']]);
    $reviews = $stmt->fetchAll(PDO::FETCH_ASSOC);
    // Get the overall rating and total amount of reviews
    $stmt = $pdo->prepare('SELECT AVG(rating) AS overall_rating, COUNT(*) AS total_reviews FROM reviews WHERE page_id = ?');
    $stmt->execute([$_GET['page_id']]);
    $reviews_info = $stmt->fetch(PDO::FETCH_ASSOC);
} else {
    exit('Please provide the page ID.');
}
?>

With the above code, we use a GET request that will retrieve the page ID (e.g. reviews.php?page_id=1), and with that page ID, we can retrieve all the results from our database ordered by the review submit date (newest first).

Not only do we need the reviews from our database but also need to calculate the average rating that is based on all the reviews retrieved. To do that we can execute a separate query that will calculate the average rating using the MySQL AVG() function and retrieve the total number of reviews using the MySQL COUNT() function.

Also take note prepared statements will prevent SQL injection and therefore you don't need to be concerned about SQL injection or security issues.

After this line:

if (isset($_GET['page_id'])) {

Add:

PHP Copy
if (isset($_POST['name'], $_POST['rating'], $_POST['content'])) {
    // Insert a new review (user submitted form)
    $stmt = $pdo->prepare('INSERT INTO reviews (page_id, name, content, rating, submit_date) VALUES (?,?,?,?,NOW())');
    $stmt->execute([$_GET['page_id'], $_POST['name'], $_POST['content'], $_POST['rating']]);
    exit('Your review has been submitted!');
}

What this will do is insert a new review into our reviews table in our database, but only if the user has submitted the "write review" form as this form will contain fields for name, rating, and content, which can then subsequently be retrieved with the $_POST variable.

At the very end of the file add (just after the PHP closing tag):

PHP Copy
<div class="overall_rating">
    <span class="num"><?=number_format($reviews_info['overall_rating'], 1)?></span>
    <span class="stars"><?=str_repeat('&#9733;', round($reviews_info['overall_rating']))?></span>
    <span class="total"><?=$reviews_info['total_reviews']?> reviews</span>
</div>
<a href="#" class="write_review_btn">Write Review</a>
<div class="write_review">
    <form>
        <input name="name" type="text" placeholder="Your Name" required>
        <input name="rating" type="number" min="1" max="5" placeholder="Rating (1-5)" required>
        <textarea name="content" placeholder="Write your review here..." required></textarea>
        <button type="submit">Submit Review</button>
    </form>
</div>
<?php foreach ($reviews as $review): ?>
<div class="review">
    <h3 class="name"><?=htmlspecialchars($review['name'], ENT_QUOTES)?></h3>
    <div>
        <span class="rating"><?=str_repeat('&#9733;', $review['rating'])?></span>
        <span class="date"><?=time_elapsed_string($review['submit_date'])?></span>
    </div>
    <p class="content"><?=htmlspecialchars($review['content'], ENT_QUOTES)?></p>
</div>
<?php endforeach ?>

The above code is the template for our review system, which will iterate the reviews array and populate them accordingly. The form to write the review and the overall rating also appear in the code.

The average rating and the total number of reviews will be displayed at the top, which has a range from 1 to 5 stars.

That's everything you need to do on the back-end. Next, we'll be using AJAX to retrieve the results and populate them on our webpage.

5. Implementing the Review System into our Webpage with AJAX

Now that we have created the back-end code, we can proceed to create the front-end code with AJAX (JavaScript).

We can implement the reviews to any webpage as long as the page ID is specified. The template used below is just an example of how you can implement the review system.

Create the index.html file and add:

HTML Copy
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Reviews System</title>
		<link href="style.css" rel="stylesheet" type="text/css">
		<link href="reviews.css" rel="stylesheet" type="text/css">
	</head>
	<body>
	    <nav class="navtop">
	    	<div>
	    		<h1>Reviews System</h1>
	    	</div>
	    </nav>
		<div class="content home">
			<h2>Reviews</h2>
			<p>Check out the below reviews for our website.</p>
		</div>
	</body>
</html>

The above code is the template we'll be using to test out the review system

After this line:

<p>Check out the below reviews for our website.</p>

Add:

HTML Copy
<div class="reviews"></div>
<script>
const reviews_page_id = 1;
fetch("reviews.php?page_id=" + reviews_page_id).then(response => response.text()).then(data => {
	document.querySelector(".reviews").innerHTML = data;
	document.querySelector(".reviews .write_review_btn").onclick = event => {
		event.preventDefault();
		document.querySelector(".reviews .write_review").style.display = 'block';
		document.querySelector(".reviews .write_review input[name='name']").focus();
	};
	document.querySelector(".reviews .write_review form").onsubmit = event => {
		event.preventDefault();
		fetch("reviews.php?page_id=" + reviews_page_id, {
			method: 'POST',
			body: new FormData(document.querySelector(".reviews .write_review form"))
		}).then(response => response.text()).then(data => {
			document.querySelector(".reviews .write_review").innerHTML = data;
		});
	};
});
</script>

And now if we navigate to http://localhost/phpreviews/index.html in our browser, it should appear as the following:

http://localhost/phpreviews/index.html
PHP and AJAX Review System

If we want to change the page ID, we can update the reviews_page_id variable. You can implement the above code to any webpage, the only code you need to update is the reviews_page_id variable, every page should have a unique page ID.

You can put the AJAX code in a separate JavaScript file if you prefer, just remember to specify the reviews_page_id variable.

That's everything you need to do to create a review system with PHP, MySQL and AJAX.

Conclusion

Congratulations! You've successfully created a review system with PHP, MySQL, and AJAX!

If you've enjoyed this article, consider sharing it with the social links below and/or drop a comment.

Enjoy coding!

If you would like to support us, consider purchasing a package below as it will greatly help us create more tutorials and keep our server up and running. Packages include improved code and more features.

Advanced

Source code
Database SQL file
Secure Review System
Sort by feature
Pagination feature
Upload images/photos feature
1 review per user feature
Approval feature
AJAX Indicator (circle loader) feature
JavaScript Class
AJAX integration
SCSS file
Admin Panel
— Dashboard
— View/create/edit reviews
— Approve reviews
— Filters
— Settings
Commented code
Free updates
Free support (bugs and minor issues)
User Guide
* Payments are processed with PayPal/Stripe.
* Advanced package also includes the tutorial source.

$15.00

PayPal
Download
Stripe
Download
Cryptocurrency
Download

For more detailed information regarding the advanced package, click here.