Home PHP

PHP and MySQL Shopping Cart Tutorial – Using SESSIONS To Store Cart Data

shopping-cart-in-php-sessions

If you want to build your own online shopping cart from scratch, we have good news for you!

This post can help you get it done because we will build a simple shopping cart script today.

We will use PHP, MySQL and PHP sessions to complete this task.

A lot of people use a ready-made software for this.

But for coders like us, it is important to learn and experience how to do it. We can create more features like making the system more secured, add some unique functionality and more.

Your imagination can be the only limit.

This post will have the following contents:

1.0 Is This Code For Me?
2.0 Source Code Output Preview
3.0 File Structure

4.0 Prepare the database
4.1 Database Design
4.2 Create MySQL Tables
4.3 Database connection file

5.0 Prepare the user interface
5.1 Download jQuery and Bootstrap
5.2 Create layout files
5.3 Add Custom CSS

6.0 Display Products
6.1 Create products.php
6.2 Include PHP Classes
6.3 Create “product” object file
6.4 Create “product image” object file
6.5 Connect to the database
6.6 Initialize action and pagination
6.7 Display messages based on action
6.8 Request data from the database
6.9 Add “read” and “count” methods
6.10 Template to display products
6.11 Add “readFirst()” method
6.12 Make “add to cart” button work
6.13 Create pagination file

7.0 How to add to cart?
7.1 Create add_to_cart.php
7.2 Create cart.php
7.3 Display message based on action
7.4 Display cart items
7.5 Read products by IDs

8.0 How to update cart?
8.1 Update cart quantity with JavaScript
8.2 PHP script to update cart
8.3 How to remove product on cart?
8.4 Create the checkout page
8.5 Create place_order.php

9.0 How to make the product page?
9.1 Create product.php
9.2 Read product details
9.3 Read one product method
9.4 Display product thumbnails
9.5 Read images related to product
9.6 Display product image
9.7 Make image hover work
9.8 Display product details
9.9 Render ‘Cart’ button

10.0 What People Say About This Code?
11.0 Download the LEVEL 1 Source Code
12.0 Download the LEVEL 2 Source Code
13.0 Download the LEVEL 3 Source Code
14.0 Download the PHP Shopping Cart SYSTEM

15.0 What’s Next?
16.0 Related Source Code
17.0 Some Notes

1.0 Is This Code For Me?

The source codes in this page is NOT for you if:

  • You are already an expert in PHP & MySQL programming.
  • You have a lot of time to code a shopping cart system from scratch.
  • You are not that interested in learning PHP & MySQL programming.

But, this SOURCE CODE is FOR YOU if:

  • You want to SAVE huge amount of development time.
  • You want to develop your own shopping cart system from scratch.
  • You determined to learn how to make a web application in PHP & MySQL.

But if you are an expert in PHP & MySQL programming and would like to take a look at our code, please do so! We’d love to hear your response and great insights! The comments section below is always open for anyone with questions and suggestions.

2.0 Source Code Output Preview

Below are some screenshots of our script’s output. You can click an image to view the larger version of it. Use the left and right arrow to navigate through the screenshots.

Please note that the following images are just output previews. New features might be added already the time you are reading this.

Note: If the output preview is in video format, please click the play button instead.

2.1 LEVEL 1 Source Code Output


2.2 LEVEL 2 Source Code Output


2.3 LEVEL 3 Source Code Output


If you need the live demo link of our LEVEL 2 or LEVEL 3 source code, send an email request to mike@codeofaninja.com with a subject:

“DEMO REQUEST: PHP Shopping Cart with SESSIONS LEVEL 2” or
“DEMO REQUEST: PHP Shopping Cart with SESSIONS LEVEL 3”

The LEVEL 2 and LEVEL 3 source code outputs proves that you can add and customize more features. It’s easier and faster if you will learn by following our tutorial below.

Downloading our source codes is your huge advantage as well. For now, let’s proceed to the step by step tutorial of our LEVEL 1 source code. Enjoy!

3.0 File Structure

The following folders and files are included in the source code. It will have more meaning if you will see the code inside the folders and files.

├─ config/
├─── database.php
├─ dev/
├─── shop_cart_sessions_1.sql
├─── readme.txt
├─ images/
├─ libs/
├─── css/
├────── bootstrap/
├─── js/
├────── jquery.js
├─ objects/
├─── product_image.php
├─── product.php
├─ uploads/
├─── images/
├─ .htaccess
├─ add_to_cart.php
├─ cart.php
├─ checkout.php
├─ layout_foot.php
├─ layout_head.php
├─ navigation.php
├─ paging.php
├─ place_order.php
├─ product.php
├─ products.php
├─ read_products_template.php
├─ remove_from_cart.php
├─ update_quantity.php

4.0 Prepare the database

4.1 Database Design

Our database name will be called “shop_cart_sessions_1”, and we will have two (2) tables.
php shopping cart tutorial database design

4.2 Create MySQL Tables

You may run the following SQL queries on our “shop_cart_sessions_1” database.

Create the products table. This table will hold products record.

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 product_images table. This table will hold images related to product.

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 ;

The products and product_images table will not fully work without the sample data and images in the “/uploads/images/” directory.

You’ll have to download the SQL and image files. Use the download button below. What will you get? A ZIP file with shop_cart_sessions_1.sql and 28 image files inside (1.30 MB).

Once downloaded, you may import the SQL file using PhpMyAdmin. Put the image files in “/uploads/images/” directory. You are now one step closer to the output shown in section 2.1 above.

4.3 Database connection file

Create “config” folder and inside it, create “database.php” file with 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;
	}

}
?>

5.0 Prepare the user interface

5.1 Download jQuery and Bootstrap

Download jQuery library here. Create “libs” folder. Inside it, create “js” folder. Put jQuery library inside “js” folder.

Download Bootstrap framework here. Inside “libs” folder, create “css” folder. Put bootstrap library inside “css” folder.

5.2 Create layout files

Layout files are needed so we can use the same header and footer code.

Create “layout_head.php” with the following code.

<?php
$_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>

    <!-- Bootstrap CSS -->
	<link href="libs/css/bootstrap/dist/css/bootstrap.css" rel="stylesheet" media="screen">

    <!-- HTML5 Shiv and Respond.js IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
    <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->

    <!-- custom css for users -->
    <link href="libs/css/user.css" rel="stylesheet" media="screen">

</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 “layout_foot.php” with the following code.

		</div>
		<!-- /row -->

	</div>
	<!-- /container -->

<!-- jQuery library -->
<script src="libs/js/jquery.js"></script>

<!-- bootstrap JavaScript -->
<script src="libs/css/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="libs/css/bootstrap/docs-assets/js/holder.js"></script>

</body>
</html>

5.3 Add Custom CSS

Inside “libs/css” directory, create user.css with the following code inside it.

.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;
}

6.0 Display Products

6.1 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_head.php';

// contents will be here 

// layout footer code
include 'layout_foot.php';
?>

6.2 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";

6.3 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;
	}
}

6.4 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;
	}
}

6.5 Connect to the database

Put the following code after the code on the previous section.

// get database connection
$database = new Database();
$db = $database->getConnection();

// initialize objects
$product = new Product($db);
$product_image = new ProductImage($db);

6.6 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

6.7 Display messages based on action

We’ll display messages basedon given action. Put the following code after “include ‘layout_head.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>";

6.8 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>";
}

6.9 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];
}

6.10 Template to display products

The previous section 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";
?>

6.11 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;
}

6.12 Make “add to cart” button work

<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>

6.13 Create pagination file

The previous section 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>";
?>

7.0 How to add to cart?

7.1 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);
}
?>

7.2 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_head.php';

// contents will be here 

// layout footer 
include 'layout_foot.php';
?>

7.3 Display message based on action

We’ll display message on cart.php based on given action. Put the following code after “include ‘layout_head.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>";

7.4 Display cart items

Put the following code based on 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>&#36;" . 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>&#36;" . 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>";
}

7.5 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;
}

8.0 How to update cart?

8.1 Update cart quantity with JavaScript

We have the ‘update’ button on cart.php file. When that button was clicked, a javascript code is triggered. Put the following code inside “$(document).ready(function(){” of layout_foot.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;
});

8.2 PHP script to update cart

The previous section will not work without the update_quantity.php file with the following code inside 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);
?>

8.3 How to remove product on cart?

We have the ‘remove’ button on cart.php file. When that button was clicked, the remove_from_cart.php file with the following code will be executed.

<?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);
?>

8.4 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_head.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>&#36;" . 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>&#36;" . 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_foot.php';
?>

8.5 Create place_order.php

We’ll use this file to show a “thank you” message and remove all items in the cart.

<?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_head.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_foot.php';
?>

9.0 How to make the product page?

9.1 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_head.php';

// content will be here

// include page footer HTML
include_once 'layout_foot.php';
?>

9.2 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;

9.3 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'];
}

9.4 Display product thumbnails

When these product thumbnails were hovered, it displayes a larger version of the image. It is Amazon-style. Put the following code after the previous section’s 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>";

9.5 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;
}

9.6 Display product image

Only one product image are displayed at a time. This part displays the larger product image based on the hovered product thumbnail. Put the following code after the previous section’s 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>";

9.7 Make image hover work

Put the following jQuery code inside “$(document).ready(function(){” of layout_foot.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();
});

9.8 Display product details

This part display product price, description and category. Put the following code after the previous section’s code.

echo "<div class='col-md-5'>";

	echo "<div class='product-detail'>Price:</div>";
	echo "<h4 class='m-b-10px price-description'>&#36;" . 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>";

9.9 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.

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>";

10.0 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 6.99 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

11.0 Download the LEVEL 1 Source Code

You can get the source code by following the whole, well detailed tutorial above. But isn’t it more convenient if you can just download the complete source code we used, and play around it?

There’s a small fee in getting the complete source code, it is small compared to the:

✔ Value or skill upgrade it can bring you, orYES
✔ Income you can get from your website project or business.YES
✔ Precious time you save.YES
✔ Expert advice you can get from us, just in case you have any questions related to the source code.YES

For a limited time, I will give you the source code for a low price. DOWNLOAD THE SOURCE CODE LEVEL you desire by clicking its the BUY button below.

FEATURELEVEL 1
Learn to code a simple cart functionYes
List all products from MySQL databaseYes
Pagination on products list pageYES
Add to cart action buttonYes
Remove from cart action buttonYes
Update cart quantityYes
Checkout PageYes
Place order / Thank you pageYes
Amazon-style product details pageYes
Change image on hover of thumbnailYes
Show message about a product added to cartYes
Show message about a product removed from cartYes
Navigation bar highlights which page is selectedYes
Cart link shows count of products added in the cartYes
Show message if no products found in databaseYes
Show message if no product found in cartYes
Bootstrap enabled UIYes
Cart page that lists all products added to cartYes
Auto-compute total cost of all products added to cartYes
PDO extension usedYes
Step by step tutorialYes
Free code updatesYes
Free support for 6 monthsYes
LEVEL 1: BUY AND
DOWNLOAD USING

* You can use your debit or credit card with PayPal.

12.0 Download the LEVEL 2 Source Code

FEATURELEVEL 2
All features of LEVEL 1 source codeYES
Navigation bar has drop down of product categoriesYES
Highlight selected category in drop downYES
Categories are retrieved from the databaseYES
Show products by categoryYES
List products under a category with paginationYES
Search productYES
Search results with paginationYES
Search box located on upper right corner of navigation barYES
Search box requires search term before clicking the search buttonYES
Add to cart action buttonYES
Quantity text box beside the add to cart buttonYES
Quantity text box required to be a numberYES
Quantity text box required to have a minimum value of 1, negative value not allowedYES
Remember the page number where the user clicked the “Add to cart” buttonYES
Quantity drop down options based on available stockYES
Well formatted money valueYES
Check out button with cart iconYES
Product image viwable in lightboxYES
Shows number of stock leftYES
Stock decreases once checked outYES
Order saved in orders and order_items table in the databaseYES
Emtpy cart buttonYES
Emtpy cart confirmation pop upYES
Bootstrap enabled UIYES
Cart page that lists all products added to cartYES
Quantity text box beside update quantity buttonYES
Show price, category and stocks left in product list pageYES
Auto-compute total cost of all products added to cartYES
Used PDO bindParam() to prevent SQL injection in MySQL queriesYES
Used PHP htmlspecialchars() to prevent XSS attacksYES
SQL file is in the “dev” folderYES
PDO extension usedYES
Free code updatesYES
Free support for 6 monthsYES
LEVEL 2: BUY AND
DOWNLOAD USING

* You can use your debit or credit card with PayPal.

13.0 Download the LEVEL 3 Source Code

The LEVEL 3 source code is also known as our “PHP Shopping Cart & Ordering Module”. As you have seen on our demo, 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

14.0 Download the “PHP Shopping Cart SYSTEM” Source Code

Many of you requested this source code. You needed a shopping cart system with user management (merchant and customer), product management, category management, order management, security and more features based on our source codes here in codeofaninja.com. Click here to learn more.

15.0 What’s Next?

We just learned how to code an online shopping cart from scratch using PHP SESSIONS.

But did you know that we can create the 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

16.0 Related Source Codes

The following related source code tutorials can be very useful to further improve your skills.

PHP CRUD Tutorials
1.0 PHP & MySQL CRUD Tutorial for Beginners
2.0 PHP, MySQL & OOP CRUD Tutorial
3.0 PHP, MySQL & AJAX CRUD Tutorial
4.0 PHP, MySQL & AngularJS CRUD Tutorial
5.0 PHP, MySQL & React CRUD Tutorial
PHP Shopping Cart Tutorials
1.0 Shopping Cart Tutorial using SESSIONS
2.0 Shopping Cart Tutorial using COOKIES
3.0 Shopping Cart Tutorial using MySQL
PHP Web Application Source Codes
PHP Shopping Cart System
PayPal Integration In PHP
PHP Login System

17.0 Some Notes

#1 Found An Issue?

If you found a problem with this code, we can solve it faster via Email or FB message, please send me a message via email mike@codeofaninja.com, or via our official Facebook page!

Please be more detailed about your issue. Best if you can provide an error message and your test or page URL. Thanks!

Please feel free to comment if you have any questions, suggestions, found something wrong or want to contribute to this code.

#2 Become a true Ninja!

We constantly add new tutorials and improve our existing tutorials and source codes. Be one of the first to know an update by subscribing to our FREE newsletter. CLICK HERE TO SUBSCRIBE FOR FREE!

#3 Thank You!

Thank you for studying our tutorial about PHP Shopping Cart Tutorial using SESSIONS!