
This post is about PHP Shopping Cart Tutorial using SESSIONS. Previously, we learned how to build a Shopping Cart with PHP & MySQL where we used a MySQL database to store products added to the cart. This time, we will use PHP session variables to store products added to the cart.
Final output
PHP Shopping Cart Tutorial using SESSIONS
At the end of this tutorial, you will achieve the following features.
- Products list with pagination
- Product page
- Add to cart function
- Update cart function
- Delete product from cart function
- Cart page
- Checkout page
- Thank you page
Prepare the database
Database Design
Our database name will be called “shop_cart_sessions_1
“, and we will have two (2) tables. The image below is a visual representation of our database tables and how they are related.
Create a database
Start Apache and MySQL. If you’re using XAMPP like me, you can do it using its control panel.

Once Apache and MySQL are running, open your PhpMyAdmin (http://localhost/phpmyadmin). Create a new database. Use “shop_cart_sessions_1” as database name. Click the “Create” button.
Create “products” table
In this section, we will create the “products” table (using PhpMyAdmin) on the database we just created. This table will store the product records.
Run the SQL statement using PhpMyAdmin. Click “shop_cart_sessions_1” database. Click the “SQL” tab. Copy the SQL statement below and paste it in the text area. Click the “Go” button.
CREATE TABLE IF NOT EXISTS `products` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(512) NOT NULL, `description` text NOT NULL, `price` decimal(10,2) NOT NULL, `created` datetime NOT NULL, `modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='products that can be added to cart' AUTO_INCREMENT=41 ;
Create “categories” table
This table will hold images related to the product. Run the following SQL statement on PhpMyAdmin as well. Follow the same steps we did on the “products” table.
CREATE TABLE IF NOT EXISTS `product_images` ( `id` int(11) NOT NULL AUTO_INCREMENT, `product_id` int(11) NOT NULL, `name` varchar(512) NOT NULL, `created` datetime NOT NULL, `modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='image files related to a product' AUTO_INCREMENT=105 ;
Download sample data
The products and product_images table will not fully work without the sample data and related image files. Use the following button to download the ZIP file.
Extract and import data
Once downloaded, please extract the files. Import the SQL file using PhpMyAdmin.
Put the image files in “php-shopping-cart-using-sessions-level-1/uploads/images/” directory. That directory does not exist yet. Follow the steps below to create it.
Create “php-shopping-cart-using-sessions-level-1” folder and open it. This is our project’s main folder. Create the “uploads” folder and open it. Create an “images” folder and open it. Copy and paste the images on this directory.
Database connection file
This file will be used to get establish a database connection. Create “config
” folder and open it. Create “database.php
” file and open it. Put the following code.
<?php // used to get mysql database connection class Database{ // specify your own database credentials private $host = "localhost"; private $db_name = "shop_cart_sessions_1"; private $username = "root"; private $password = ""; public $conn; // get the database connection public function getConnection(){ $this->conn = null; try{ $this->conn = new PDO("mysql:host=" . $this->host . ";dbname=" . $this->db_name, $this->username, $this->password); }catch(PDOException $exception){ echo "Connection error: " . $exception->getMessage(); } return $this->conn; } } ?>
Output
Our PhpMyAdmin should look like the image below. A database with two tables.

We don’t have an actual program output yet because we only set up the database. Let’s continue our tutorial below to achieve more outputs.
Create the layout files
The layout files contain code that can be re-used on each web page. The look of our pages will be consistent because of these header and footer layout files.
Create header layout file
This “layout_header.php
” file will be included at the beginning of the PHP files that will need it. This way, we won’t have to write the same header codes every time.
We use the Bootstrap framework to make our project look good. If you’re not yet familiar with Bootstrap, you may learn from our Bootstrap tutorial here.
Create “layout_header.php
” file. Place the following code. By the way, please note that after we put a code on a file, always save your changes. You can use CTRL+S to save if you’re using Windows like me.
This code contains our session variable that will hold the products added to the cart. We put it here so we don’t need to re-initialize it on every page.
The title tags contain PHP code that will make our page title dynamic. Bootstrap CSS and our custom CSS are included inside the head tags. Our navigation bar is inside the navigation.php file, we will create this file later.
<?php // session variable that will hold products added to cart $_SESSION['cart']=isset($_SESSION['cart']) ? $_SESSION['cart'] : array(); ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title><?php echo isset($page_title) ? $page_title : "The Code of a Ninja"; ?></title> <!-- Latest compiled and minified Bootstrap CSS --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" /> <!-- our custom CSS --> <link rel="stylesheet" href="libs/css/custom.css" /> </head> <body> <?php include 'navigation.php'; ?> <!-- container --> <div class="container"> <div class="row"> <div class="col-md-12"> <div class="page-header"> <h1><?php echo isset($page_title) ? $page_title : "The Code of a Ninja"; ?></h1> </div> </div>
Create footer layout file
This “layout_footer.php” will be included at the end of the PHP files that will need it. This way, we won’t have to write the same footer codes every time.
We are using jQuery and Bootstrap’s JavaScript in the footer layout file. jQuery is required by Bootstrap’s JavaScript which is needed for features like a navigation drop-down
Create a “layout_footer.php” file. Put the following code.
</div> <!-- /row --> </div> <!-- /container --> <!-- jQuery (necessary for Bootstrap's JavaScript plugins) --> <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script> <!-- Latest compiled and minified Bootstrap JavaScript --> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> <!-- custom script will be here --> </body> </html>
Create navigation layout file
Create “navigation.php
” file. Put the following code. This code will display the navigation bar with “Products” and “Cart” menu links. It will also display the number of products added to the cart.
<!-- navbar --> <div class="navbar navbar-default navbar-static-top" role="navigation"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="products.php">XYZ Webstore</a> </div> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <!-- highlight if $page_title has 'Products' word. --> <li <?php echo $page_title=="Products" ? "class='active'" : ""; ?>> <a href="products.php" class="dropdown-toggle">Products</a> </li> <li <?php echo $page_title=="Cart" ? "class='active'" : ""; ?> > <a href="cart.php"> <?php // count products in cart $cart_count=count($_SESSION['cart']); ?> Cart <span class="badge" id="comparison-count"><?php echo $cart_count; ?></span> </a> </li> </ul> </div><!--/.nav-collapse --> </div> </div> <!-- /navbar -->
Create custom CSS file
This custom.css file is where our custom styles are located.
- Open “
php-shopping-cart-using-sessions-level-1
” folder. - Open “
libs
” folder. - Open “
css
” folder. - Create “
custom.css
” file. - Place the following code.
.text-align-center{ text-align:center; } .f-w-b{ font-weight:bold; } .display-none{ display:none; } .w-5-pct{ width:5%; } .w-10-pct{ width:10%; } .w-15-pct{ width:15%; } .w-20-pct{ width:20%; } .w-25-pct{ width:25%; } .w-30-pct{ width:30%; } .w-35-pct{ width:35%; } .w-40-pct{ width:40%; } .w-45-pct{ width:45%; } .w-50-pct{ width:50%; } .w-55-pct{ width:55%; } .w-60-pct{ width:60%; } .w-65-pct{ width:65%; } .w-70-pct{ width:70%; } .w-75-pct{ width:75%; } .w-80-pct{ width:80%; } .w-85-pct{ width:85%; } .w-90-pct{ width:90%; } .w-95-pct{ width:95%; } .w-100-pct{ width:100%; } .m-t-0px{ margin-top:0px; } .m-b-10px{ margin-bottom:10px; } .m-b-20px{ margin-bottom:20px; } .m-b-30px{ margin-bottom:30px; } .m-b-40px{ margin-bottom:40px; } .stock-text { font-weight: bold; color: #008a00; } .stock-text-red{ font-weight:bold; color:#b12704; } .product-detail { font-weight: bold; margin: 0 0 5px 0; } .blueimp-gallery>.prev, .blueimp-gallery>.next{ border:none; } .update-quantity-form { width: 150px; float: left; margin: 0 10px 0 0; } .cart-row { border-bottom: thin solid #f1f1f1; overflow: hidden; width: 100%; padding: 20px 0 20px 0; } .product-link{ color:#000000; } .product-link:hover{ color:#000000; text-decoration:none; } .product-img-thumb { margin: 0 0 10px 0; width: 100%; cursor: pointer; }
Output
The files we created in this section is meant to be used within another PHP file. If we will try to run the files, we won’t see anything meaningful yet.
If you will run layout_header.php file, it will look like this.
The custom.css looks like this.
The navigation.php looks like this.
The footer.php is blank. Let’s continue on the next section to see something meaningful.
Display Products
Create products.php
Now we are going to start displaying products from the database. Create products.php
with the following basic code.
<?php // start session session_start(); // set page title $page_title="Products"; // page header html include 'layout_header.php'; // contents will be here // layout footer code include 'layout_footer.php'; ?>
Include PHP Classes
Put the following code after “session_start();” code of the previous section.
// connect to database include 'config/database.php'; // include objects include_once "objects/product.php"; include_once "objects/product_image.php"; // class instances will be here
Create “product” object file
Create “objects
” folder. Inside it, create product.php
file with the following code.
<?php // 'product' object class Product{ // database connection and table name private $conn; private $table_name="products"; // object properties public $id; public $name; public $price; public $description; public $category_id; public $category_name; public $timestamp; // constructor public function __construct($db){ $this->conn = $db; } }
Create “product image” object file
Create product_image.php
file inside “objects
” folder.
<?php // 'product image' object class ProductImage{ // database connection and table name private $conn; private $table_name = "product_images"; // object properties public $id; public $product_id; public $name; public $timestamp; // constructor public function __construct($db){ $this->conn = $db; } }
Connect to the database
Open products.php file. Replace // class instances will be here
comment with the following code.
// get database connection $database = new Database(); $db = $database->getConnection(); // initialize objects $product = new Product($db); $product_image = new ProductImage($db);
Initialize action and pagination
Put the following code after the code on the previous section.
// to prevent undefined index notice $action = isset($_GET['action']) ? $_GET['action'] : ""; // for pagination purposes $page = isset($_GET['page']) ? $_GET['page'] : 1; // page is the current page, if there's nothing set, default is page 1 $records_per_page = 6; // set records or rows of data per page $from_record_num = ($records_per_page * $page) - $records_per_page; // calculate for the query LIMIT clause
Display messages based on action
We’ll display messages basedon given action.
Put the following code after include ‘layout_header.php
‘; code.
echo "<div class='col-md-12'>"; if($action=='added'){ echo "<div class='alert alert-info'>"; echo "Product was added to your cart!"; echo "</div>"; } if($action=='exists'){ echo "<div class='alert alert-info'>"; echo "Product already exists in your cart!"; echo "</div>"; } echo "</div>";
Request data from the database
Request data from the database. Put the following code after the code on the previous section.
// read all products in the database $stmt=$product->read($from_record_num, $records_per_page); // count number of retrieved products $num = $stmt->rowCount(); // if products retrieved were more than zero if($num>0){ // needed for paging $page_url="products.php?"; $total_rows=$product->count(); // show products include_once "read_products_template.php"; } // tell the user if there's no products in the database else{ echo "<div class='col-md-12'>"; echo "<div class='alert alert-danger'>No products found.</div>"; echo "</div>"; }
Add “read” and “count” methods
The previous section will not work without the following code inside “objects/product.php” object file.
// read all products function read($from_record_num, $records_per_page){ // select all products query $query = "SELECT id, name, description, price FROM " . $this->table_name . " ORDER BY created DESC LIMIT ?, ?"; // prepare query statement $stmt = $this->conn->prepare( $query ); // bind limit clause variables $stmt->bindParam(1, $from_record_num, PDO::PARAM_INT); $stmt->bindParam(2, $records_per_page, PDO::PARAM_INT); // execute query $stmt->execute(); // return values return $stmt; } // used for paging products public function count(){ // query to count all product records $query = "SELECT count(*) FROM " . $this->table_name; // prepare query statement $stmt = $this->conn->prepare( $query ); // execute query $stmt->execute(); // get row value $rows = $stmt->fetch(PDO::FETCH_NUM); // return count return $rows[0]; }
Template to display products
The products.php
won’t work without “read_products_template.php
“, so create that file and put the following code.
<?php if(!isset($_SESSION['cart'])){ $_SESSION['cart']=array(); } while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){ extract($row); // creating box echo "<div class='col-md-4 m-b-20px'>"; // product id for javascript access echo "<div class='product-id display-none'>{$id}</div>"; echo "<a href='product.php?id={$id}' class='product-link'>"; // select and show first product image $product_image->product_id=$id; $stmt_product_image=$product_image->readFirst(); while ($row_product_image = $stmt_product_image->fetch(PDO::FETCH_ASSOC)){ echo "<div class='m-b-10px'>"; echo "<img src='uploads/images/{$row_product_image['name']}' class='w-100-pct' />"; echo "</div>"; } // product name echo "<div class='product-name m-b-10px'>{$name}</div>"; echo "</a>"; // add to cart button echo "<div class='m-b-10px'>"; if(array_key_exists($id, $_SESSION['cart'])){ echo "<a href='cart.php' class='btn btn-success w-100-pct'>"; echo "Update Cart"; echo "</a>"; }else{ echo "<a href='add_to_cart.php?id={$id}&page={$page}' class='btn btn-primary w-100-pct'>Add to Cart</a>"; } echo "</div>"; echo "</div>"; } include_once "paging.php"; ?>
Add “readFirst()” method
Add “readFirst()” method in “objects/product_image.php
” file. The previous section will not work without it.
// read the first product image related to a product function readFirst(){ // select query $query = "SELECT id, product_id, name FROM " . $this->table_name . " WHERE product_id = ? ORDER BY name DESC LIMIT 0, 1"; // prepare query statement $stmt = $this->conn->prepare( $query ); // sanitize $this->id=htmlspecialchars(strip_tags($this->id)); // bind prodcut id variable $stmt->bindParam(1, $this->product_id); // execute query $stmt->execute(); // return values return $stmt; }
Make “add to cart” button work
Open layout_footer.php
file. Replace <!-- custom script will be here -->
comment with the following code.
<script> $(document).ready(function(){ // add to cart button listener $('.add-to-cart-form').on('submit', function(){ // info is in the table / single product layout var id = $(this).find('.product-id').text(); var quantity = $(this).find('.cart-quantity').val(); // redirect to add_to_cart.php, with parameter values to process the request window.location.href = "add_to_cart.php?id=" + id + "&quantity=" + quantity; return false; }); }); </script>
Create pagination file
The read_products_template.php
file won’t work without the paging.php
file. Create paging.php
with the following code.
<?php echo "<div class='col-md-12'>"; echo "<ul class='pagination m-b-20px m-t-0px'>"; // button for first page if($page>1){ echo "<li><a href='{$page_url}' title='Go to the first page.'>"; echo "First Page"; echo "</a></li>"; } $total_pages = ceil($total_rows / $records_per_page); // range of links to show $range = 2; // display links to 'range of pages' around 'current page' $initial_num = $page - $range; $condition_limit_num = ($page + $range) + 1; for ($x=$initial_num; $x<$condition_limit_num; $x++) { // be sure '$x is greater than 0' AND 'less than or equal to the $total_pages' if (($x > 0) && ($x <= $total_pages)) { // current page if ($x == $page) { echo "<li class='active'><a href=\"#\">$x <span class=\"sr-only\">(current)</span></a></li>"; } // not current page else { echo "<li><a href='{$page_url}page=$x'>$x</a></li>"; } } } // button for last page if($page<$total_pages){ echo "<li>"; echo "<a href='" . $page_url . "page={$total_pages}' title='Last page is {$total_pages}.'>"; echo "Last Page"; echo "</a>"; echo "</li>"; } echo "</ul>"; echo "</div>"; ?>
Output
Run your products.php file on the browser http://localhost/php-shopping-cart-using-sessions-level-1/products.php. You should see an output like the image below.

How to add to cart?
Create add_to_cart.php
Create add_to_cart.php
file because when ‘Add to cart’ button was clicked, that file with the following code inside will be executed.
<?php // start session session_start(); // get the product id $id = isset($_GET['id']) ? $_GET['id'] : ""; $quantity = isset($_GET['quantity']) ? $_GET['quantity'] : 1; $page = isset($_GET['page']) ? $_GET['page'] : 1; // make quantity a minimum of 1 $quantity=$quantity<=0 ? 1 : $quantity; // add new item on array $cart_item=array( 'quantity'=>$quantity ); /* * check if the 'cart' session array was created * if it is NOT, create the 'cart' session array */ if(!isset($_SESSION['cart'])){ $_SESSION['cart'] = array(); } // check if the item is in the array, if it is, do not add if(array_key_exists($id, $_SESSION['cart'])){ // redirect to product list and tell the user it was added to cart header('Location: products.php?action=exists&id=' . $id . '&page=' . $page); } // else, add the item to the array else{ $_SESSION['cart'][$id]=$cart_item; // redirect to product list and tell the user it was added to cart header('Location: products.php?action=added&page=' . $page); } ?>
Create cart.php
Create cart.php
with the following basic code.
<?php // start session session_start(); // connect to database include 'config/database.php'; // include objects include_once "objects/product.php"; include_once "objects/product_image.php"; // get database connection $database = new Database(); $db = $database->getConnection(); // initialize objects $product = new Product($db); $product_image = new ProductImage($db); // set page title $page_title="Cart"; // include page header html include 'layout_header.php'; // contents will be here // layout footer include 'layout_footer.php'; ?>
Display message based on action
We’ll display message on cart.php based on given action.
Put the following code after include ‘layout_header.php
‘; of the previous section.
$action = isset($_GET['action']) ? $_GET['action'] : ""; echo "<div class='col-md-12'>"; if($action=='removed'){ echo "<div class='alert alert-info'>"; echo "Product was removed from your cart!"; echo "</div>"; } else if($action=='quantity_updated'){ echo "<div class='alert alert-info'>"; echo "Product quantity was updated!"; echo "</div>"; } echo "</div>";
Display cart items
Put the following code after the code of the previous section.
if(count($_SESSION['cart'])>0){ // get the product ids $ids = array(); foreach($_SESSION['cart'] as $id=>$value){ array_push($ids, $id); } $stmt=$product->readByIds($ids); $total=0; $item_count=0; while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){ extract($row); $quantity=$_SESSION['cart'][$id]['quantity']; $sub_total=$price*$quantity; // ================= echo "<div class='cart-row'>"; echo "<div class='col-md-8'>"; echo "<div class='product-name m-b-10px'><h4>{$name}</h4></div>"; // update quantity echo "<form class='update-quantity-form'>"; echo "<div class='product-id' style='display:none;'>{$id}</div>"; echo "<div class='input-group'>"; echo "<input type='number' name='quantity' value='{$quantity}' class='form-control cart-quantity' min='1' />"; echo "<span class='input-group-btn'>"; echo "<button class='btn btn-default update-quantity' type='submit'>Update</button>"; echo "</span>"; echo "</div>"; echo "</form>"; // delete from cart echo "<a href='remove_from_cart.php?id={$id}' class='btn btn-default'>"; echo "Delete"; echo "</a>"; echo "</div>"; echo "<div class='col-md-4'>"; echo "<h4>$" . number_format($price, 2, '.', ',') . "</h4>"; echo "</div>"; echo "</div>"; // ================= $item_count += $quantity; $total+=$sub_total; } echo "<div class='col-md-8'></div>"; echo "<div class='col-md-4'>"; echo "<div class='cart-row'>"; echo "<h4 class='m-b-10px'>Total ({$item_count} items)</h4>"; echo "<h4>$" . number_format($total, 2, '.', ',') . "</h4>"; echo "<a href='checkout.php' class='btn btn-success m-b-10px'>"; echo "<span class='glyphicon glyphicon-shopping-cart'></span> Proceed to Checkout"; echo "</a>"; echo "</div>"; echo "</div>"; } // no products were added to cart else{ echo "<div class='col-md-12'>"; echo "<div class='alert alert-danger'>"; echo "No products found in your cart!"; echo "</div>"; echo "</div>"; }
Read products by IDs
The previous section will not work without the following “readByIds()” method inside “objects/product.php
” file.
// read all product based on product ids included in the $ids variable // reference http://stackoverflow.com/a/10722827/827418 public function readByIds($ids){ $ids_arr = str_repeat('?,', count($ids) - 1) . '?'; // query to select products $query = "SELECT id, name, price FROM " . $this->table_name . " WHERE id IN ({$ids_arr}) ORDER BY name"; // prepare query statement $stmt = $this->conn->prepare($query); // execute query $stmt->execute($ids); // return values from database return $stmt; }
Output
When user click the “Add to cart” button.
Go to the cart page by clicking the “Cart” option on the navigation bar.
How to update cart?
Update cart quantity with JavaScript
We have the ‘update’ button on cart.php file. When that button was clicked, a javascript code is triggered.
Place the following code inside $(document).ready(function(){ of layout_footer.php file.
// update quantity button listener $('.update-quantity-form').on('submit', function(){ // get basic information for updating the cart var id = $(this).find('.product-id').text(); var quantity = $(this).find('.cart-quantity').val(); // redirect to update_quantity.php, with parameter values to process the request window.location.href = "update_quantity.php?id=" + id + "&quantity=" + quantity; return false; });
PHP script to update cart
The previous section will not work without this file.
Create update_quantity.php
file. Place the following code and save it.
<?php session_start(); // get the product id $id = isset($_GET['id']) ? $_GET['id'] : 1; $quantity = isset($_GET['quantity']) ? $_GET['quantity'] : ""; // make quantity a minimum of 1 $quantity=$quantity<=0 ? 1 : $quantity; // remove the item from the array unset($_SESSION['cart'][$id]); // add the item with updated quantity $_SESSION['cart'][$id]=array( 'quantity'=>$quantity ); // redirect to product list and tell the user it was added to cart header('Location: cart.php?action=quantity_updated&id=' . $id); ?>
How to remove product on cart?
We have the ‘remove’ button on cart.php
file. When that button was clicked, it will trigger remove_from_cart.php file.
Create remove_from_cart.php
file. Place the following code and save it.
<?php // start session session_start(); // get the product id $id = isset($_GET['id']) ? $_GET['id'] : ""; $name = isset($_GET['name']) ? $_GET['name'] : ""; // remove the item from the array unset($_SESSION['cart'][$id]); // redirect to product list and tell the user it was added to cart header('Location: cart.php?action=removed&id=' . $id); ?>
Create the checkout page
The checkout page looks like the cart page but the items cannot be updated or removed. It just like the summary of orders. Create checkout.php
with the following code.
<?php // start session session_start(); // connect to database include 'config/database.php'; // include objects include_once "objects/product.php"; include_once "objects/product_image.php"; // get database connection $database = new Database(); $db = $database->getConnection(); // initialize objects $product = new Product($db); $product_image = new ProductImage($db); // set page title $page_title="Checkout"; // include page header html include 'layout_header.php'; if(count($_SESSION['cart'])>0){ // get the product ids $ids = array(); foreach($_SESSION['cart'] as $id=>$value){ array_push($ids, $id); } $stmt=$product->readByIds($ids); $total=0; $item_count=0; while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){ extract($row); $quantity=$_SESSION['cart'][$id]['quantity']; $sub_total=$price*$quantity; //echo "<div class='product-id' style='display:none;'>{$id}</div>"; //echo "<div class='product-name'>{$name}</div>"; // ================= echo "<div class='cart-row'>"; echo "<div class='col-md-8'>"; echo "<div class='product-name m-b-10px'><h4>{$name}</h4></div>"; echo $quantity>1 ? "<div>{$quantity} items</div>" : "<div>{$quantity} item</div>"; echo "</div>"; echo "<div class='col-md-4'>"; echo "<h4>$" . number_format($price, 2, '.', ',') . "</h4>"; echo "</div>"; echo "</div>"; // ================= $item_count += $quantity; $total+=$sub_total; } // echo "<div class='col-md-8'></div>"; echo "<div class='col-md-12 text-align-center'>"; echo "<div class='cart-row'>"; if($item_count>1){ echo "<h4 class='m-b-10px'>Total ({$item_count} items)</h4>"; }else{ echo "<h4 class='m-b-10px'>Total ({$item_count} item)</h4>"; } echo "<h4>$" . number_format($total, 2, '.', ',') . "</h4>"; echo "<a href='place_order.php' class='btn btn-lg btn-success m-b-10px'>"; echo "<span class='glyphicon glyphicon-shopping-cart'></span> Place Order"; echo "</a>"; echo "</div>"; echo "</div>"; } else{ echo "<div class='col-md-12'>"; echo "<div class='alert alert-danger'>"; echo "No products found in your cart!"; echo "</div>"; echo "</div>"; } include 'layout_footer.php'; ?>
Create place_order.php
We’ll use this file to show a “thank you” message and remove all items in the cart.
Create place_order.php
file. Place the following code.
<?php // start session session_start(); // remove items from the cart session_destroy(); // set page title $page_title="Thank You!"; // include page header HTML include_once 'layout_header.php'; echo "<div class='col-md-12'>"; // tell the user order has been placed echo "<div class='alert alert-success'>"; echo "<strong>Your order has been placed!</strong> Thank you very much!"; echo "</div>"; echo "</div>"; // include page footer HTML include_once 'layout_footer.php'; ?>
Output
When user click the “Update” button in the cart page.
If user click the “Delete” button.
The checkout page.
When user click the “Place Order” button.
How to make the product page?
Create product.php
Create product.php
with the following basic code.
<?php // start session session_start(); // include classes include_once "config/database.php"; include_once "objects/product.php"; include_once "objects/product_image.php"; // get database connection $database = new Database(); $db = $database->getConnection(); // initialize objects $product = new Product($db); $product_image = new ProductImage($db); // include page header HTML include_once 'layout_header.php'; // content will be here // include page footer HTML include_once 'layout_footer.php'; ?>
Read product details
Put the following code after “$product_image = new ProductImage($db);” code of the previous section.
// get ID of the product to be edited $id = isset($_GET['id']) ? $_GET['id'] : die('ERROR: missing ID.'); // set the id as product id property $product->id = $id; // to read single record product $product->readOne(); // set page title $page_title = $product->name; // product thumbnail will be here
Read one product method
The previous section will not work without the “readOne()” method. Add the following method inside “objects/product.php
” file.
// used when filling up the update product form function readOne(){ // query to select single record $query = "SELECT name, description, price FROM " . $this->table_name . " WHERE id = ? LIMIT 0,1"; // prepare query statement $stmt = $this->conn->prepare( $query ); // sanitize $this->id=htmlspecialchars(strip_tags($this->id)); // bind product id value $stmt->bindParam(1, $this->id); // execute query $stmt->execute(); // get row values $row = $stmt->fetch(PDO::FETCH_ASSOC); // assign retrieved row value to object properties $this->name = $row['name']; $this->description = $row['description']; $this->price = $row['price']; }
Display product thumbnails
When these product thumbnails were hovered, it displayes a larger version of the image. It is Amazon-style.
Open product.php
file. Replace // product thumbnail will be here
comment with the following code.
// set product id $product_image->product_id=$id; // read all related product image $stmt_product_image = $product_image->readByProductId(); // count all relatd product image $num_product_image = $stmt_product_image->rowCount(); echo "<div class='col-md-1'>"; // if count is more than zero if($num_product_image>0){ // loop through all product images while ($row = $stmt_product_image->fetch(PDO::FETCH_ASSOC)){ // image name and source url $product_image_name = $row['name']; $source="uploads/images/{$product_image_name}"; echo "<img src='{$source}' class='product-img-thumb' data-img-id='{$row['id']}' />"; } }else{ echo "No images."; } echo "</div>"; // product image will be here
Read images related to product
The previous section section will not work without the “readByProductId()” method inside “objects/product_image.php
” file.
// read all product image related to a product function readByProductId(){ // select query $query = "SELECT id, product_id, name FROM " . $this->table_name . " WHERE product_id = ? ORDER BY name ASC"; // prepare query statement $stmt = $this->conn->prepare( $query ); // sanitize $this->product_id=htmlspecialchars(strip_tags($this->product_id)); // bind prodcut id variable $stmt->bindParam(1, $this->product_id); // execute query $stmt->execute(); // return values return $stmt; }
Only one product image are displayed at a time. This part displays the larger product image based on the hovered product thumbnail.
Open product.php
file. Replace // product image will be here
comment with the following code.
echo "<div class='col-md-4' id='product-img'>"; // read all related product image $stmt_product_image = $product_image->readByProductId(); $num_product_image = $stmt_product_image->rowCount(); // if count is more than zero if($num_product_image>0){ // loop through all product images $x=0; while ($row = $stmt_product_image->fetch(PDO::FETCH_ASSOC)){ // image name and source url $product_image_name = $row['name']; $source="uploads/images/{$product_image_name}"; $show_product_img=$x==0 ? "display-block" : "display-none"; echo "<a href='{$source}' target='_blank' id='product-img-{$row['id']}' class='product-img {$show_product_img}'>"; echo "<img src='{$source}' style='width:100%;' />"; echo "</a>"; $x++; } }else{ echo "No images."; } echo "</div>"; // product details will be here
Make image hover work
Put the following jQuery code inside “$(document).ready(function(){” of layout_footer.php
file.
// change product image on hover $(document).on('mouseenter', '.product-img-thumb', function(){ var data_img_id = $(this).attr('data-img-id'); $('.product-img').hide(); $('#product-img-'+data_img_id).show(); });
Display product details
This part display product price, description and category.
Open product.php
file. Replace // product details will be here
comment with the following code.
echo "<div class='col-md-5'>"; echo "<div class='product-detail'>Price:</div>"; echo "<h4 class='m-b-10px price-description'>$" . number_format($product->price, 2, '.', ',') . "</h4>"; echo "<div class='product-detail'>Product description:</div>"; echo "<div class='m-b-10px'>"; // make html $page_description = htmlspecialchars_decode(htmlspecialchars_decode($product->description)); // show to user echo $page_description; echo "</div>"; echo "<div class='product-detail'>Product category:</div>"; echo "<div class='m-b-10px'>{$product->category_name}</div>"; echo "</div>";
Render ‘Cart’ button
Now we will display ‘Add to cart’ button if the product is not yet added to cart. Else, we will display ‘update cart’ button.
Place the following code after the previous section’s code.
echo "<div class='col-md-2'>"; // if product was already added in the cart if(array_key_exists($id, $_SESSION['cart'])){ echo "<div class='m-b-10px'>This product is already in your cart.</div>"; echo "<a href='cart.php' class='btn btn-success w-100-pct'>"; echo "Update Cart"; echo "</a>"; } // if product was not added to the cart yet else{ echo "<form class='add-to-cart-form'>"; // product id echo "<div class='product-id display-none'>{$id}</div>"; echo "<div class='m-b-10px f-w-b'>Quantity:</div>"; echo "<input type='number' value='1' class='form-control m-b-10px cart-quantity' min='1' />"; // enable add to cart button echo "<button style='width:100%;' type='submit' class='btn btn-primary add-to-cart m-b-10px'>"; echo "<span class='glyphicon glyphicon-shopping-cart'></span> Add to cart"; echo "</button>"; echo "</form>"; } echo "</div>";
Output
When user click on any product image in products.php page, he will land to a product page that looks like the image below.
If user hovers on any of those thumbnail or small images, the big image will change as well. The “Add to cart” button is working as well.
Here’s the output when the product is already added to cart.
If user click the “Update Cart” button, he will land on the cart page where he can update the cart quantity.
What People Say About This Code?
I’m so glad that this code delights other people. The following are some of them from the comments section!
★★★★★ “Hey Mike, my name is Leonardo from Argentina. I’ve been reading your blog since like 4 months from now, and I really must say: your tutorials are very good, they has helped me in many of my works… Well, thank you very much man. I really admire your work.” ~ Leonardo
★★★★★ “Man, your tut’s are awesome. Im so glad ive found your blog. Big respect!” ~ Milos
★★★★★ “I bought your level-2 source code and it was so good, very big help for me. It was worth it. Thank you very much!” ~ Ashley Deanna Plata
★★★★★ “Hello, This is a great script and I have paid for your work (it Worth it).” ~ Louis Blais
★★★★★ “Words can’t express how grateful I am for the work and the articles you post, had some troubles with doing somethings but your articles as per usual hit the hammer right on the head. They are a great way for expanding upon later too!” ~ Jeremy Smith
Download source code
We highly recommend following our well-detailed, step-by-step tutorial above first. Nothing beats experience when it comes to learning. But we believe you will learn faster if you’ll see the final source code as well. We consider it as your additional guide.
Imagine the value or skill upgrade it can bring you. The additional income you can get from your work, projects, or business. The precious time you save.
List of features
Features | LEVEL 1 Source code | LEVEL 2 Source code |
---|---|---|
Learn to code a simple cart function | YES | YES |
List all products from the MySQL database | YES | YES |
Pagination on the products list page | YES | YES |
Add to cart action button | YES | YES |
Remove from the cart action button | YES | YES |
Update product quantity | YES | YES |
Checkout page, place order page & thank you page | YES | YES |
Amazon-style product details page | YES | YES |
Change image on hover of thumbnail | YES | YES |
Show message about a product added to cart | YES | YES |
Show message about a product removed from cart | YES | YES |
Navigation bar highlights which page is selected | YES | YES |
Show number of products added to cart in the cart menu | YES | YES |
Show message if no products found in database | YES | YES |
Show message if no product found in the cart | YES | YES |
Bootstrap enabled UI | YES | YES |
Cart page that lists all products added to cart | YES | YES |
Auto compute the total cost of all products added to the cart | YES | YES |
The navigation bar has to drop down of product categories | NO | YES |
Highlight selected category in the dropdown | NO | YES |
Categories are retrieved from the database | NO | YES |
Show products by category with pagination | NO | YES |
Search products with paginated results | NO | YES |
Search box located on the upper right corner of the navigation bar | NO | YES |
Search box requires search term before clicking the search button | NO | YES |
Input quantity beside the add to cart button with value required to be a number | NO | YES |
Quantity input required to have a minimum value of 1, negative value not allowed | NO | YES |
Remember the page number where the user clicked the “Add to cart” button | NO | YES |
Quantity drop-down options based on available stock | NO | YES |
Well formatted money value | NO | YES |
Product image viewable in a lightbox pop-up | NO | YES |
Shows number of stock left | NO | YES |
Stock decreases once checked out | NO | YES |
Order saved in orders and order_items table in the database | NO | YES |
Empty cart button with confirmation popup | NO | YES |
Show price, category, and stocks left on the product list page | NO | YES |
Free code updates and support | YES | YES |
How to run the source code?
Once you downloaded the source code, here’s how you can run it.
- Extract the files to your server directory.
- Go to your PhpMyAdmin, create a database with a name “shop_cart_sessions_1”.
- Import the “shop_cart_sessions_1.sql” file located in the “README” folder.
- You might need to change database credentials in /config/database.php
- Run “products.php”, this is the main PHP file. We do not have index.php
Need more features?
PHP Shopping Cart Module. You can download our “PHP Shopping Cart & Ordering Module” source code. It has several features you need to learn more about how to handle the users, shopping cart, and ordering using the PHP & MySQL technology. CLICK HERE TO LEARN MORE
PHP Shopping Cart System. You can download our “PHP Shopping Cart System” source code as well. Many of you requested this type of source code and not it is here!
You needed a shopping cart system with user management (merchant and customer), product management, order management, security, and more features based on our source codes here in codeofaninja.com. CLICK HERE TO LEARN MORE.
What’s Next?
Option 1: We just learned how to code an online shopping cart from scratch using PHP SESSIONS. But did you know that we can create almost the same functions using another PHP mechanism called COOKIES?
If you’re excited to learn this new concept, let us go to the next tutorial: PHP Shopping Cart Tutorial Using COOKIES
Option 2: This next tutorial is the start of our JavaScript programming journey. Go to our next tutorial: How To Create a Simple REST API in PHP – Step By Step Guide!
Related Tutorials
[adinserter block=”1″]
Some Notes
[adinserter block=”3″]
Thank you for studying our PHP Shopping Cart Tutorial using SESSIONS! Please share our tutorial with your friend.
Leave a Reply