Building an online Store [con't]
In this section we are going to look at the script that lists the books and also at the composition of the connect script that holds the database connection details. To recap, the storefront is one of three parts that make up an online store, the other two being the shopping cart and payments. So far, we have built the index, which is capable of listing all of the categories or genres of books that are available in our store. The user then has the option to view books in those categories by clicking on the genre that they want to browse. Once again, I would like to stress that this is but one of several ways in which you can implement an online store. For some, this might be the best approach and for others it might not. Either way, I would not recommend using this application unless you are sure that it meets your requirements and that you have modified its security. This application should be considered as a foundation upon which to build your own sophisticated online store. Having said that, the application itself is functioning according to the requirements of an online shopping front and I have put in sufficient security measures to prevent most types of attacks or enough to make attacks difficult. Where the application is lacking in security, it is up to you, the reader, to put them in place BEFORE implementing this in the real world.
Below is a screenshot of both the index and list_books script:
Later, the user will be able to view individual details of the books, but for now, let's concentrate on the script that list the books in a category. What happens here is that the script receives a catid (category id) variable from the index page and uses that id to retrieve all of the books that are in that category. Start a new PHP document, save it as listbooks.php and add the following code:
Ok, so let's step through the code. The first line retrieves the database connection details and connects to the database server:
The connect.php file contains all that the script needs to connect to the database. A security precaution that you can take to guard against password sniffers and the like is to put the connect.php file in a directory other than your public folder. The next section actually filters the data that is sent over from the index page. In this case it is the category id. So what do we know about the category id? We know from the database schema in the previous article that it is numeric, so when we filter the data, this is one of the things we need to verify. In addition to checking that it has actually been submitted, we have to make sure to escape it properly BEFORE using it in a MySQL query. Why do we do all this? Because first of all, the category id that is sent over does not originate from you and is therefore not to be trusted. In other words, it can be tampered with and pose a security risk for exactly that reason. Secondly, the category id provides a way into your application and therefore gives access or control to any attacker that wants to use it for malicious intent. It is therefore very important that we take as much precaution as possible. Now, the code below checks that a category id is submitted and then validates this value by using the "is_numeric()" function:
If the category id is indeed numeric, than the code continues to retrieve the books for the category that matches the category id. If you remember the database schema that we created previously, you will also remember that the books table had a field called "genID" in which we store the genre id for a particular book. This id is key to this query, since we need it to retrieve the name of the genre that this book belongs to. So what we need is the name of the genre and also other details of the books. Based on what we need to get out of the database, our query is not going to be straight forward as you can see below:
The query matches the genID in the books table to the gen_id in the genre table to get the name of genre that the book belongs to and at the same time retrieves all the books that matches the genID in the books table. This is made possible by using the INNER JOIN construct. Something else that I want to focus your attention to in this piece of code is the mysql_escape_string() function:
From a security point of view, it is absolutely critical that you escape all variables with this function BEFORE using them in a MySQL query, for reasons that I've already stated before.
The reminder of the PHP code just collects all the MySQL errors that might occur and store them in a variable to display later:
From a security point of view, you should really only echo a mysql_error() for debugging purposes during development. As most developers know, PHP errors tend to reveal more information than is really needed, and in so doing can lead to a security vulnerability. When you deploy an application and want to effectively deal with MySQL or other errors, then I would recommend using some kind of error logging facility or use the PHP logs if you have access--but avoid echoing them to the screen unless you are in the process of developing.
The HTML of the page actually just sets up the page to print the names of the books and all relevant information.
The connection script contains the information needed to connect to the database as well as useful information such as today's date. We will be using the date when inserting data into a table later on:
You will also notice that a session is started using the session_start() function, right at the top; this is because we are going to need the session id to identify the user in the shopping cart section. In fact, the session id will be key to making our shopping cart function.
In part 2, we will deal with the final part of the shopping front: viewing book details.
Original: January 3, 2010