PHP & mysql shopping cart project (Live example + source code)
Today we are going to learn about php & mysql shopping cart project with Live example and source code. We will use HTML, Bootstrap, jQuery for front-end and PHP & MySQL for backend coding to build PHP shopping cart.
We will also provide you with the source code of PHP shopping cart for free of cost. You can learn and even can modify it as per your requirements too.
Features of php & mysql shopping cart project including source code
You will be able to use the following features of this project.
- Product listing from MySQL database
- Add to cart the product
- Login and registration
- Add and remove cart items
- Search product by name
It will iterate the products array on the product listing page. We have used a js library list.js to create a dynamic search for products.
We have used jQuery ajax to create add to cart, remove from cart etc. without any page refresh. If you try to add a product to a shopping cart without login, it will add cart items to a php session as an array and once user logged in, it will save all the items to the user’s cart. Then the user can see all those items in his/her cart.
Local setup of php shopping cart project code
Go to your localhost directory like htdocs or www. Then open your command terminal and run the following command
git clone https://github.com/SATPAL-BHARDWAJ/php-ecommerce.git
It will clone the php-ecommerce project to your local server. Now, open your web browser and type localhost/path-to/php-ecommerce it will run our project.
Now, you need to change a few things, open your code editor and add this project there. Open the file app/Include.php and config/include.php and replace the BASE_PATH constant value with your project directory.
For example, my project is in the following directory
htdocs/projects/php-ecommerce
So,
define('BASE_PATH', '/projects/php-ecommerce');
Now, go to config/conn.php and replace the following dbname, username and password as per your local server credentials.
private $server = "mysql:host=localhost;dbname=QSale"; private $username = "root"; private $password = "";
File structure
The PHP shopping cart site has following files and directories.
Database Setup
We are using mysql PDO to connect with databases. You will find this file in the config/conn.php
directory. You can update your database credentials here.
Navigate to http://localhost/phpmyadmin
and create a database named qsale
or anything else that you want.
You will get the Sql file with the source code from my git-repo, you need to import that file to this created database.
Product listing page for php & mysql shopping cart example
Let’s build the product listing page for our php shopping cart site. So, the product gallery page will be visible to all users, loggedIn and without login.
Users can click on the add to cart button and it will directly add the product to the cart or cart session (if the user is not loggedIn).
How, technically, does it work?
Below is our product listing html with php loop for products. We are getting products array from mysql database.
<?php $conn = $pdo->open(); try{ $stmt = $conn->prepare("SELECT * FROM products"); $stmt->execute(); $products = $stmt->fetchAll(); //dd($products); } catch(PDOException $e){ echo "There is some problem in connection: " . $e->getMessage(); } $pdo->close(); $addedProducts = cartProducts(); ?> <div class='container py-5' id="qsale_products"> <div class="pricing-header p-3 pb-md-4 mx-auto text-center"> <!-- <h1 class="display-4 fw-normal">All Gadgets</h1> --> <img class="img-fluid w-25" src="./resources/assets/images/undraw_social_friends.svg"/> </div> <?php include "./resources/components/search.php"; ?> <div class="row row-cols-1 row-cols-lg-2 mb-3 list"> <?php foreach($products as $product) { ?> <div class="col my-4"> <div class="wrapper"> <div class="product-img"> <img class="img-fluid" src="<?php echo './resources/assets/images/'.$product['photo'] ?>"> </div> <div class="product-info"> <div class="product-text"> <h1 class="name"><?php echo substr($product['name'], 0, 20) ?></h1> <h2>$<?php echo $product['price'] ?></h2> <div><?php echo $product['description'] ?></div> </div> <div class="product-price-btn"> <button data-product-id="<?php echo $product['id']; ?>" type="button" class="add-to-cart-btn-js"><?php echo in_array($product['id'], $addedProducts) ? 'Added' : 'add to cart' ?> </button> </div> </div> </div> </div> <?php } ?> </div> </div>
Add product to the shopping cart with ajax
We are using a css class selector for the add to cart button and we will use this selector in the app.js file.
$(function () { $('.add-to-cart-btn-js').on('click', function () { var product_id = $(this).data('product-id'); console.log({ product_id }); var data = { id: product_id, quantity: 1 } $.post("app/AddToCart.php", data, (response) => { console.log({ response }); if (!response.error) { updateCartQty(1); $(this).text('Added'); } showAlerts((!response.error ? 'success' : 'error'), response.message); }, "json"); }) }) /* Cart page */ var total = 0; $(function () { $(document).on('click', '.cart_delete', function (e) { e.preventDefault(); var id = $(this).data('id'); $.ajax({ type: 'POST', url: 'app/CartDelete.php', data: { id: id }, dataType: 'json', success: function (response) { if (!response.error) { getDetails(); getCart(); getTotal(); updateCartQty(-1); } showAlerts((!response.error ? 'success' : 'error'), response.message); } }); }); $(document).on('click', '.minus', function (e) { e.preventDefault(); var id = $(this).data('id'); var qty = $('#qty_' + id).val(); if (qty > 1) { qty--; } $('#qty_' + id).val(qty); $.ajax({ type: 'POST', url: 'app/CartUpdate.php', data: { id: id, qty: qty, }, dataType: 'json', success: function (response) { if (!response.error) { getDetails(); getCart(); getTotal(); } } }); }); $(document).on('click', '.add', function (e) { e.preventDefault(); var id = $(this).data('id'); var qty = $('#qty_' + id).val(); qty++; $('#qty_' + id).val(qty); $.ajax({ type: 'POST', url: 'app/CartUpdate.php', data: { id: id, qty: qty, }, dataType: 'json', success: function (response) { if (!response.error) { getDetails(); getCart(); getTotal(); } } }); }); getDetails(); getTotal(); }); function getDetails() { $.ajax({ type: 'POST', url: "app/CartController.php", dataType: 'json', success: function (response) { console.log({ response }); $('#tbody').html(response); getCart(); }, }) } function getTotal() { $.ajax({ type: 'POST', url: "app/CartTotal.php", dataType: 'json', success: function (response) { total = response; } }); } function updateCartQty(cart_count) { var my_cart = $('.my-cart-btn-js'); var notify_dot = my_cart.find('.notify-dot'); if (notify_dot.length > 0) { var count = notify_dot.text(); notify_dot.text((Number(count) + cart_count)); } else { var cart_text = my_cart.text(); my_cart.html(`<span class="notify-dot">1</span> ${cart_text}`); } } function showAlerts(type, message) { var errors = $('.errors-js'); var alert = '.alert-success'; errors.find('.alert').each((index, element) => { console.log(index, element); if (!$(element).hasClass('d-none')) { $(element).addClass('d-none'); } }); if (type === 'error') { alert = '.alert-danger'; } else if (type === 'info') { alert = '.alert-info'; } errors.find(alert).removeClass('d-none').text(message); }
We are using ajax to save products to the cart table. It will add a smooth transition to add product to the cart.
We are also adding a cart items count with the help of js function called updateCartQty()
, So that when a user adds a product to the cart it will add a cart count over the “My Cart” menu in the navbar by using notify-dot selector.
It will tell the user how many products are in the cart.
PHP shopping cart items
Let’s build a cart items listing page.
When the user clicks on the “my cart” menu from the navbar, it will load the cart page and we have called the ajax on load of the shopping cart page in app.js file. Something like below,
$(function(){ getDetails(); }) function getDetails(){ $.ajax({ type: 'POST', url: "app/CartController.php", dataType: 'json', success: function(response){ console.log({response}); $('#tbody').html(response); getCart(); }, }) }
We are adding ajax response as html to the table body in the cart.php.
<table class="table table-bordered"> <thead> <th></th> <th>Photo</th> <th>Name</th> <th>Price</th> <th width="20%">Quantity</th> <th>Subtotal</th> </thead> <tbody id="tbody"> </tbody> </table>
We have prepared the products html data in the CartController.php and then have returned it as ajax response.
try { $total = 0; $stmt = $conn->prepare("SELECT *, cart.id AS cartid FROM cart LEFT JOIN products ON products.id=cart.product_id WHERE user_id=:user"); $stmt->execute(['user'=>$user['id']]); foreach($stmt as $row){ $image = (!empty($row['photo'])) ? 'resources/assets/images/'.$row['photo'] : 'images/noimage.jpg'; $subtotal = $row['price']*$row['quantity']; $total += $subtotal; $output .= " <tr> <td><i data-id='".$row['cartid']."' class='fa fa-close cart_delete cursor-pointer'></i> </td> <td><img src='".$image."' width='30px' height='30px'></td> <td>".$row['name']."</td> <td>$ ".number_format($row['price'], 2)."</td> <td class='input-group'> <span class='input-group-btn'> <button type='button' id='minus' class='btn btn-default btn-flat minus' data-id='".$row['cartid']."'><i class='fa fa-arrow-down'></i></button> </span> <input type='text' class='form-control' value='".$row['quantity']."' id='qty_".$row['cartid']."'> <span class='input-group-btn'> <button type='button' id='add' class='btn btn-default btn-flat add' data-id='".$row['cartid']."'><i class='fa fa-arrow-up'></i> </button> </span> </td> <td>$ ".number_format($subtotal, 2)."</td> </tr> "; } $output .= " <tr> <td colspan='5' align='right'><b>Total</b></td> <td><b>$ ".number_format($total, 2)."</b></td> <tr> "; } catch(PDOException $e){ $output .= $e->getMessage(); } $pdo->close(); echo json_encode($output);
Update cart quantity or remove cart items
In the cart page, we can remove cart items and can also increase/decrease the quantity. We are doing all these things with the help of below js.
$(function(){ $(document).on('click', '.cart_delete', function(e){ e.preventDefault(); var id = $(this).data('id'); $.ajax({ type: 'POST', url: 'app/CartDelete.php', data: {id:id}, dataType: 'json', success: function(response){ if(!response.error){ getDetails(); getCart(); getTotal(); updateCartQty(-1); } showAlerts( (!response.error ? 'success' : 'error'), response.message ); } }); }); $(document).on('click', '.minus', function(e){ e.preventDefault(); var id = $(this).data('id'); var qty = $('#qty_'+id).val(); if(qty>1){ qty--; } $('#qty_'+id).val(qty); $.ajax({ type: 'POST', url: 'app/CartUpdate.php', data: { id: id, qty: qty, }, dataType: 'json', success: function(response){ if(!response.error){ getDetails(); getCart(); getTotal(); } } }); }); $(document).on('click', '.add', function(e){ e.preventDefault(); var id = $(this).data('id'); var qty = $('#qty_'+id).val(); qty++; $('#qty_'+id).val(qty); $.ajax({ type: 'POST', url: 'app/CartUpdate.php', data: { id: id, qty: qty, }, dataType: 'json', success: function(response){ if(!response.error){ getDetails(); getCart(); getTotal(); } } }); }); getDetails(); getTotal(); }); function getDetails(){ $.ajax({ type: 'POST', url: "app/CartController.php", dataType: 'json', success: function(response){ console.log({response}); $('#tbody').html(response); getCart(); }, }) } function getTotal(){ $.ajax({ type: 'POST', url: "app/CartTotal.php", dataType: 'json', success:function(response){ total = response; } }); } function updateCartQty( cart_count ) { var my_cart = $('.my-cart-btn-js'); var notify_dot = my_cart.find('.notify-dot'); if ( notify_dot.length > 0 ) { var count = notify_dot.text(); notify_dot.text( (Number(count) + cart_count) ); } else { var cart_text = my_cart.text(); my_cart.html(`<span class="notify-dot">1</span> ${cart_text}`); } } function showAlerts( type, message ) { var errors = $('.errors-js'); var alert = '.alert-success'; errors.find('.alert').each((index, element) => { console.log(index, element); if ( !$(element).hasClass('d-none') ) { $(element).addClass('d-none'); } }); if ( type === 'error' ) { alert = '.alert-danger'; } else if ( type === 'info' ) { alert = '.alert-info'; } errors.find(alert).removeClass('d-none').text(message); }
Routing System
Routing System Instead of file names with php extension in the url like https://example.com/cart.php can be https://example.com/cart.
Sounds amazing!
We have created a helper file where we have defined an array of routes. Now we can use this route array to get the actual file path. You can see this thing in the resources/index.php file.
Oh I forgot!
We have created the htaccess file to redirect all http calls to a single index.php file. So that we could use our routing system instead of the default php file calls.
<?php $Routes = [ '/' => './resources/home.php', '/login' => './resources/auth/auth.php', '/signup' => './resources/auth/auth.php', '/app/login' => './app/auth/LoginController.php', '/app/signup' => './app/auth/RegisterController.php', '/logout' => './app/auth/LogoutController.php', '/cart' => './resources/cart.php', '/app/cart' => './app/CartController.php', '/app/cart-total' => './app/CartTotal.php', ];
Common helper functions
We have one more interesting feature that is helper functions. We have created a helper file which helps us to use common functions in the whole site.
It simplifies our code and our code will look short, easy to understand and maintainable. We have created the following common functions which are very useful in our site.
- url() : To get the url with the base path.
- layout() : To get the layout from resources directory
- redirect() : To redirect to a particular path
There are other functions too. You will get to know when you go through the code.
<?php if( !function_exists('url') ) { function url( $url = null, $parameter = [] ) { echo BASE_PATH."{$url}"; } } if( !function_exists('layout') ) { function layout( $file ) { include_once "./resources/layouts/{$file}.php"; } } if( !function_exists('redirect') ) { function redirect( $path ) { header('location: '.BASE_PATH.$path); exit(); } } if( !function_exists('session') ) { function session( $key ) { return isset($_SESSION[$key]) ? $_SESSION[$key] : null; } } if( !function_exists('setSession') ) { function setSession( $key, $value ) { $_SESSION[$key] = $value; } } if( !function_exists('hasSession') ) { function hasSession( $key ) { $keys = is_array($key) ? $key : array($key); $exist = false; foreach($keys as $k) { if(isset($_SESSION[$k])) { $exist = true; } } return $exist; } } if( !function_exists('removeSession') ) { function removeSession( $key ) { $keys = is_array($key) ? $key : array($key); foreach($keys as $k) { if(isset($_SESSION[$k])) { unset($_SESSION[$key]); } } } } if( !function_exists('dd') ) { function dd( ...$data ) { if ( is_array($data) ) { echo '<pre>'; print_r($data); echo '</pre>'; } else { var_dump($data); } die; } } if( !function_exists('formError') ) { function formError( $key ) { if ( isset($_SESSION['errorsBag']) && isset($_SESSION['errorsBag'][$key]) ) { $error = $_SESSION['errorsBag'][$key]; unset($_SESSION['errorsBag'][$key]); return $error; } } } if( !function_exists('HasFormError') ) { function HasFormError( $key ) { if ( isset($_SESSION['errorsBag']) && isset($_SESSION['errorsBag'][$key]) ) { return true; } return false; } } if( !function_exists('setErrorsBag') ) { function setErrorsBag( $key, $value ) { $_SESSION['errorsBag'][$key] = $value; } } if( !function_exists('hasErrorBag') ) { function hasErrorBag() { return isset($_SESSION['errorsBag']) && count($_SESSION['errorsBag']) > 0; } } if( !function_exists('showFormError') ) { function showFormError($key) { if (HasFormError( $key )) { $error = formError( $key ); echo "<span class='text-white'>*{$error}</span>"; }; } } if( !function_exists('resetErrorBag') ) { function resetErrorBag() { if( isset($_SESSION['errorsBag']) ) { unset($_SESSION['errorsBag']); } } } if ( !function_exists('setUser') ) { function setUser($id) { $pdo = new Database(); $conn = $pdo->open(); $stmt = $conn->prepare("SELECT * FROM users WHERE id=:id"); $stmt->execute(['id'=>$id]); $user = $stmt->fetch(); return $user; } } if ( !function_exists('countCartProducts') ) { function countCartProducts( $user_id ) { $pdo = new Database(); $conn = $pdo->open(); $stmt = $conn->prepare("SELECT 'id', COUNT('id') as numrows FROM cart WHERE user_id=:user_id"); $stmt->execute(['user_id'=>$user_id]); $row = $stmt->fetch(); return $row['numrows']; } } if ( !function_exists('countCart') ) { function countCart( ) { $cart_count = 0; if( isset($_SESSION['user']) ) { $cart_count = countCartProducts($_SESSION['user']); } elseif (isset($_SESSION['cart'])) { $cart_count = count($_SESSION['cart']); } return $cart_count; } } if ( !function_exists('cartProducts') ) { function cartProducts( ) { $products = []; if ( isset($_SESSION['user']) ) { $pdo = new Database(); $conn = $pdo->open(); $stmt = $conn->prepare("SELECT products.id, cart.id AS cartid FROM cart LEFT JOIN products ON products.id=cart.product_id WHERE user_id=:user"); $stmt->execute(['user'=>$_SESSION['user']]); $rows = $stmt->fetchAll(); $products = array_column($rows, 'id'); } else if ( isset($_SESSION['cart']) ) { $products = array_column($_SESSION['cart'], 'productid'); } return $products; } }
You will find a lot in the source code of this php & mysql shopping cart project with live example and source code.
Hope it will help you.