In this article we are going to build a user rating system. The aim of this system is to enable users to rate products on a website. The item(s) being rated can be anything from videos to music CDs. In our case, users will be allowed to rate books.
How the Ratings System Works
Basically, our site will present users with a list of books, that is, one book per dynamically generated page. The presentation of the book will include the title and a description. We assume that the user has read the book and is able to give an informed, sincere rating. The main page of the application will have three sections or columns. On the left side will be the navigation table, in the middle will be the book details, and on the right will be the ratings table. Figure 1 shows what the main page will look like.
Figure 1: Main Page of User Rating Application
So how does the application know which book the user has rated when the submit button is pressed? Basically, once the main page of the site is loaded, some PHP code is executed to extract the details of the books located in a database. When these details are extracted, the ID of each of the books is also extracted. This ID is then stored on the page, and when the user clicks on the submit button, the function that lies behind the ratings table grabs that ID and enters it into the database.
All the functions of the site are stored in a script called functions.php, and all major functionality is also contained therein. This helps to ensure portability and also centralizes all code, which again facilitates the separation between the presentation layers and actual PHP code. To make the site a bit more attractive (I must admit I did not spend a lot of time on this!), I created a stylesheet with the following code:
The CSS code is not much in terms of quantity: it has five styles defined, the first of which (after the body style) is the header style.
The header style is responsible for formatting all the headers on the page concerned. It basically ensures that all the headers are bold and white in color. It also dictates that the headers should be aligned right. The style is not exactly attached to any particular text as is the case with the header style. It is responsible for drawing a dotted border on the bottom of the item that is being styled.
The third style is not very different from the one above; it is also responsible for drawing a border. However, this one draws a dashed border around the entire item.
The third and final style defines a style for a subheader. It basically sets the font size at 24, aligns the text in the center, and then gives it a background color.
The Ratings System Database
I've mentioned the database a few times in the preceding section. Basically, the application has two database tables: one to store the book details and another to store the ratings information. Below is are layouts of the tables and their fields.
Books Table:
Field |
Description |
bookID |
Generates and stores a unique book ID |
title |
Stores the book title |
Description |
Stores the book description |
Ratings Table:
Field |
Description |
|
Generates and stores a unique ratings ID |
|
Stores the book ID |
|
Stores the ratings value |
|
Stores the data that a book was rated |
Note the book_id
field in the ratings table. This field creates a link between the books table and the ratings table. Because one book can get many ratings, it is important to have this link in the ratings table rather than the books table. As you will no doubt notice in the coming sections, this link will be used to extract the name of the book that is being rated.
Below is the SQL for both tables. Copy and paste it into your MySQL client to generate the tables.
SQL for the books table:
SQL for the ratings table:
The Other Scripts
The remaining scripts include:
- newbook.php  This script is responsible for enabling a user to insert new book details.
- functions.php  This script contains all the functions that are used to run the site.
- dbconn.php  This script contains the database connection details.
- ranking.php  This script displays the different positions at which books are rated.
Of the four scripts listed above, the functions script is perhaps the most important because it is at the heart of the entire application. As stated previously, it contains all the functions that the application will need to function. In the next section, we will look in detail at some of the code that is involved in generating the main page, but here is a listing of the code that is responsible for displaying the ratings box:
The function above simply lays out a form that is enclosed in a HTML table. This form is responsible for collecting the rating that is selected by the user.
In the next section, we look at some of the code that is involved in generating the main page.
The main.php Page
The main page is the first page that the user encounters when they use the rating system. The page has two parts: the first is the HTML table that hosts both the PHP code and the navigation links, and the second is the ratings table. The page is responsible for displaying the details of the book that is to be rated. The details of the book are extracted by a function called showbooks($dbname)
. The function takes one parameter, which is the database name. This variable is assigned its value by the dbconn.php
script, which contains all the database connection details. The function retrieves all the books that are stored in the database and paginates the results. This basically means that the information that is retrieved from the database is not retrieved in its entirety but is retrieved one by one at the user's convenience. The user is then able to view the book details in any order that he or she wishes to view them. Below is the code for the main page:
The code is quite substantial so let's walk through it step by step.
1. The user is presented with an HTML page that contains an HTML table enclosing a form.
2. When the form is submitted, any errors that occur are shown here:
Basically, throughout the data-validation process the code checks to see if any of the tests made on the data has failed. If so, it stores an error message in the $errmsg
variable. If this variable is set, it will be shown above.
3. The next part of the HTML page shows the navigation links. There are three links in this HTML table:
- Home  This link brings the user back to the home page.
- View Ratings  This link takes the user to the rankings page.
- Add a book  This link takes the user to the script that enables him or her to add a new book.
After the navigation panel, the code continues to build the page.
4. The next two functions are at the heart of the page. The first function (showbooks($dbname)
) retrieves the entire collection of books in the database. The second function (showbox()
) shows the ratings box. The showbooks($dbname)
function takes one parameter, which is the database name, and returns a value. This value is the ID of the book concerned. So, as the user moves back and forth through the list of book details that are stored in the books array, the ID of each of the books is stored in the $id
variable as shown below. This $id
is then fed to showbox()
, which uses this value to store the rating for the relevant book.
When I discussed the database setup of the application, I explained the link between the two database tables: book_id
. This link is located in the ratings table. It is where the $id
value will eventually be stored. The showbooks()
function also offers another useful functionality: it provides 'Next' and 'Previous' links to the user. These links enable the user to go back and forth between the listed books. And every time the user clicks on any of the two links, the $id
variable is updated.
5. The showbox()
function also takes one parameter, which is the ID number of the book that the user wants to rate. This ID is then stored internally by the function and re-surfaces when the user presses the submit button on the ratings box:
6. When the user presses the submit button, the PHP code at the top of the page immediately springs into action. The very first thing that the code does is to include all the necessary files:
7. Then it sets the error variables to their default states:
The error variables are going to be used to store error messages. The appropriately named $errmsg
variable is used to store the actual error message, while the $err
variable acts as a flag variable.
8. Next, the code checks to see if the form has been submitted. It does this by checking to see if the submit variable is set:
9. Then we reach a very important part of the code: the data-validation process, which should never be omitted at any stage as long as you are dealing with user input. Fortunately for us, we do not have to make many checks. We expect only two pieces of information from the form submission. One is the ID of the book and the other is the rating that the user selected. The book ID is numeric, so the code makes sure that is the case by using the is_numeric()
function. This function tests a value to see if it is numeric.
The second piece of information is the value that is contained in the radiobutton. This should also be numeric, but we don't have to worry about it because the number is set by us. All that the user does in this case is submit it. So the only other check that we need to make is to verify that the submitted value is not empty:
10. Assuming that no errors occurred, the code now needs to insert the rating into the ratings database table. This is done using the insert_rating()
function that is defined in the functions table. The function takes two parameters, the ID of the rated book and the actual rating:
The functions.php Script
All of the presentation and functionality that is used by the application is made possible by the functions.php script. I've chosen to do it this way, because it makes the code reusable and also helps to separate presentation from the code. The script has five functions:
showbooks($databasename)
 This function provides a list of books that are currently available in the database. It retrieves all the books with their details and then displays them in a paginated format. It provides 'previous' and 'next' links that enable a user to move from book to book. The function returns a value, which is the ID of a book. It has the following syntax:showbox($id)
 This function is responsible for creating and displaying the ratings box. The ratings box has five ratings; the number five rating is the best and the number one rating is the worst. The box has five radio buttons and a submit button. Also included in the HTML form is a hidden field that captures the ID of the book to be rated. The function itself takes one parameter, which is the ID of a book. It has the following syntax: In our application, the ID is supplied by theshowbooks()
function. This is because theshowbooks()
function is dynamic and does not show just one book for the duration of the script. It shows different books depending on the user choice. And each time the user chooses to view a new book, the ID variable is updated and fed to theshowbox()
function.insert_rating($bookid,$rating)
 Theinsert_ratings
function is responsible for adding a particular rating to the ratings table. It takes two parameters: the book ID and the actual rating. It has the following syntax:insert_book_details($title,$description)
 This function is responsible for adding new book details to the books table. It takes two parameters: the title and description of a book. It has the following syntax:rankings()
 The rankings function simply displays the book ratings.
Below is the full code listing of the functions script: