Advertisement
PHP

Build a Shopping Cart With PHP and MySQL

by

For this week’s screencast + tutorial, we’re going to teach you how to build your own shopping cart with PHP and MySQL. As you’ll find, it’s not quite as difficult as you might have thought.


Screencast Preview



Step 1

Let's begin by taking a look at the folder structure:


Structure

  • reset.css - you can get the reset from this link
  • style.css - our own css file that we will be using to style our HTML markup
  • connection.php - the file that will make our database connection
  • index.php - the template for our shopping cart
  • cart.php - the file where will able to change our products from the cart(add, remove)
  • products.php - the products listing page

Step 2

We'll start by writing the html markup and then style it. So open index.php and copy/paste the code below:

 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
	 
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
	<link rel="stylesheet" href="css/reset.css" /> 
	<link rel="stylesheet" href="css/style.css" /> 
	 
	<title>Shopping cart</title> 
 
</head> 
 
<body> 
	 
	<div id="container"> 
 
		<div id="main"> 
			 
		</div><!--end main--> 
		 
		<div id="sidebar"> 
			 
		</div><!--end sidebar--> 
 
	</div><!--end container--> 
 
</body> 
</html>

As you can see, our page has two columns: the main column and the sidebar. Let's move on to the CSS. Open the file style.css and type the code below:

 
	 
body { 
	font-family: Verdana; 
	font-size: 12px; 
	color: #444; 
} 
 
 
#container { 
	width: 700px; 
	margin: 150px auto; 
	background-color: #eee; 
	overflow: hidden; /* Set overflow: hidden to clear the floats on #main and #sidebar */ 
	padding: 15px; 
} 
 
	#main { 
		width: 490px; 
		float: left; 
	} 
 
	#sidebar { 
		width: 200px; 
		float: left; 
	}

Here's how our products page should look now:



Full Screencast



Step 3

Before we move on to the PHP/MySQL part, we need to create the database. So open phpMyadmin and follow these steps:

  1. Go to the Privileges tab, click the add new user button, and use the following settings: Username: tutorial; Host: localhost; Password: supersecretpassword;. Now make sure the Global privileges is set; then move on to the next step.
  2. Create a new database called tutorials.
  3. Create a new table called products and set the number of fields to 4. Now populate those fields so you have: id_integer - make sure it's set to INT and mark it as PRIMARY(also set it to auto_increment); name - make it VARCHAR with a length of 100; description - VARCHAR with a length of 250; price - make sure it's set to DECIMAL(2,6)
  4. Populate your table with some sample products

To save some time, I've exported my products table so that you can simply run the following query:

 
CREATE TABLE IF NOT EXISTS `products` ( 
  `id_product` int(11) NOT NULL AUTO_INCREMENT, 
  `name` varchar(100) NOT NULL, 
  `description` varchar(250) NOT NULL, 
  `price` decimal(6,2) NOT NULL, 
  PRIMARY KEY (`id_product`) 
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ; 
 
INSERT INTO `products` (`id_product`, `name`, `description`, `price`) VALUES 
(1, 'Product 1', 'Some random description', '15.00'), 
(2, 'Product 2', 'Some random description', '20.00'), 
(3, 'Product 3', 'Some random description', '50.00'), 
(4, 'Product 4', 'Some random description', '55.00'), 
(5, 'Product 5', 'Some random description', '54.00'), 
(6, 'Product 6', 'Some random description', '34.00');




Step 4

Before we move to extracting data from the database, I'll make my index.php a template for the product list and cart. So add the following code to the top of your index.php page:

 
<?php 
	session_start(); 
	require("includes/connection.php"); 
	if(isset($_GET['page'])){ 
		 
		$pages=array("products", "cart"); 
		 
		if(in_array($_GET['page'], $pages)) { 
			 
			$_page=$_GET['page']; 
			 
		}else{ 
			 
			$_page="products"; 
			 
		} 
		 
	}else{ 
		 
		$_page="products"; 
		 
	} 
?>
  1. session_start() - this is for later use; it will allow us to actually use sessions (it's vital that the session_start is written before any other data is sent to the browser).
  2. On the second line, we include the connection.php that will establish the connection to the database (we will deal with this in a second). One more thing: the difference between include and require is that if you use require and the file can't be found, the script execution will end. If you use "include", the script will continue working.
  3. Instead of copying the entire html code(the link to the css, to the js) for every file in your site, you could just make them all relative to a single file. So first, I'm checking if there's a GET variable called "page set". If it's not, I'm creating a new variable called _pages. If the GET variable called pages is set first, I want to make sure that the file which I'm going to include is a valid page.

To make this work, we need to include the file; add this line to the index.php between the div with the id of "main":

 
	<?php require($_page.".php"); ?>

Now here's the complete index.php we have now:

 
	<?php 
	session_start(); 
	require("includes/connection.php"); 
	if(isset($_GET['page'])){ 
		 
		$pages=array("products", "cart"); 
		 
		if(in_array($_GET['page'], $pages)) { 
			 
			$_page=$_GET['page']; 
			 
		}else{ 
			 
			$_page="products"; 
			 
		} 
		 
	}else{ 
		 
		$_page="products"; 
		 
	} 
 
?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
	 
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
	<link rel="stylesheet" href="css/reset.css" /> 
	<link rel="stylesheet" href="css/style.css" /> 
	 
 
	<title>Shopping Cart</title> 
 
 
</head> 
 
<body> 
	 
	<div id="container"> 
 
		<div id="main"> 
			 
			<?php require($_page.".php"); ?> 
 
		</div><!--end of main--> 
		 
		<div id="sidebar"> 
			 
		</div><!--end of sidebar--> 
 
	</div><!--end container--> 
 
</body> 
</html>

Let's create the connection to MySQL. Open connections.php and type the following:

 
	<?php 
 
	$server="localhost"; 
	$user="tutorial"; 
	$pass="supersecretpassword"; 
	$db="tutorials"; 
	 
	// connect to mysql 
	 
	mysql_connect($server, $user, $pass) or die("Sorry, can't connect to the mysql."); 
	 
	// select the db 
	 
	mysql_select_db($db) or die("Sorry, can't select the database."); 
 
?>

Step 5

Now it's time to write the markup for the products page. So go ahead open it and type the following:

 
<h1>Product List</h1> 
	<table> 
	    <tr> 
	        <th>Name</th> 
	        <th>Description</th> 
	        <th>Price</th> 
	        <th>Action</th> 
	    </tr> 
	    <tr> 
	        <td>Product 1</td> 
	        <td>Some random description</td> 
	        <td>15 $</th> 
	        <td><a href="#">Add to cart</a></td> 
	    </tr> 
	     <tr> 
	        <td>Product 2</td> 
	        <td>Some random description</td> 
	        <td>25 $</th> 
	        <td><a href="#">Add to cart</a></td> 
	    </tr> 
	</table>

Let's take a look at the page:


As you can see, it's pretty ugly. So let's style it by adding this extra CSS.

 
a {color: #48577D; text-decoration: none;} 
 
a:hover {text-decoration: underline;} 
 
h1, h2 {margin-bottom: 15px} 
 
h1 {font-size: 18px;} 
h2 {font-size: 16px} 
	#main table { 
			width: 480px; 
		} 
		 
			#main table th { 
				padding: 10px; 
				background-color: #48577D; 
				color: #fff; 
				text-align: left; 
			} 
			 
			#main table td { 
				padding: 5px; 
			} 
			#main table tr { 
				background-color: #d3dcf2; 
			}

Okay: let's have another look now:


Looks a lot better, don't you think? Below you have the complete style.css code:

 
body { 
	font-family: Verdana; 
	font-size: 12px; 
	color: #444; 
} 
 
a {color: #48577D; text-decoration: none;} 
 
a:hover {text-decoration: underline;} 
 
h1, h2 {margin-bottom: 15px} 
 
h1 {font-size: 18px;} 
h2 {font-size: 16px} 
 
#container { 
	width: 700px; 
	margin: 150px auto; 
	background-color: #eee; 
	padding:15px; 
	overflow: hidden; 
} 
 
	#main { 
		width: 490px; 
		float: left; 
	} 
	 
		#main table { 
			width: 480px; 
		} 
		 
			#main table th { 
				padding: 10px; 
				background-color: #48577D; 
				color: #fff; 
				text-align: left; 
			} 
			 
			#main table td { 
				padding: 5px; 
			} 
			 
			#main table tr { 
				background-color: #d3dcf2; 
			} 
	 
	#sidebar { 
		width: 200px; 
		float: left; 
	}

Step 6

Before we extract the product from the database, let's remove the last 2 table rows from our table(we used it only to see how our table will look like). Remove this:

 
		    <tr> 
	        <td>Product 1</td> 
	        <td>Some random description</td> 
	        <td>15 $</th> 
	        <td><a href="#">Add to cart</a></td> 
	    </tr> 
	     <tr> 
	        <td>Product 2</td> 
	        <td>Some random description</td> 
	        <td>25 $</th> 
	        <td><a href="#">Add to cart</a></td> 
	    </tr>

Great! Now in the place where the table rows were, type the following PHP code:

 
	<?php 
 
	$sql="SELECT * FROM products ORDER BY name ASC"; 
	$query=mysql_query($sql); 
	 
	while ($row=mysql_fetch_array($query)) { 
		 
?> 
		<tr> 
		    <td><?php echo $row['name'] ?></td> 
		    <td><?php echo $row['description'] ?></td> 
		    <td><?php echo $row['price'] ?>$</td> 
		    <td><a href="index.php?page=products&action=add&id=<?php echo $row['id_product'] ?>">Add to cart</a></td> 
		</tr> 
<?php 
		 
	} 
 
?>
  1. So, first we use SELECT to retrive the products, then we loop trough each row from the database and echo it to the page in a table row.
  2. You can see that the anchor links to the same page(when the user clicks the anchor the product it's added to the cart/session). We just pass some extra variables like the id of the product.

If you hover one of the add to cart links, you can see, at the bottom of the page, that the id of the product is passed.



Step 7

Let's make that anchor work by adding the following code at the top of our page:

 
<?php 
 
	if(isset($_GET['action']) && $_GET['action']=="add"){ 
		 
		$id=intval($_GET['id']); 
		 
		if(isset($_SESSION['cart'][$id])){ 
			 
			$_SESSION['cart'][$id]['quantity']++; 
			 
		}else{ 
			 
			$sql_s="SELECT * FROM products 
				WHERE id_product={$id}"; 
			$query_s=mysql_query($sql_s); 
			if(mysql_num_rows($query_s)!=0){ 
				$row_s=mysql_fetch_array($query_s); 
				 
				$_SESSION['cart'][$row_s['id_product']]=array( 
						"quantity" => 1, 
						"price" => $row_s['price'] 
					); 
				 
				 
			}else{ 
				 
				$message="This product id it's invalid!"; 
				 
			} 
			 
		} 
		 
	} 
 
?>
  1. If the GET variable called action is set and it's value is ADD, we execute the code.
  2. We make sure that the id passed through the GET variable is an integer
  3. If the id of the product is in the cart SESSION, we just increment it's quantity by 1
  4. If the id is not in the session, we need to make sure that the id passed through the GET variable exists in the database. If it does, we grab the price and create it's session. If it doesn't, we set a variable called message that will hold our error.

Let's check if that message variable is set and echo it to the page(type this code under the H1 page title):

 
		<?php 
		if(isset($message)){ 
			echo "<h2>$message</h2>"; 
		} 
	?>

Here you can see the complete products.php page.

 
<?php 
 
	if(isset($_GET['action']) && $_GET['action']=="add"){ 
		 
		$id=intval($_GET['id']); 
		 
		if(isset($_SESSION['cart'][$id])){ 
			 
			$_SESSION['cart'][$id]['quantity']++; 
			 
		}else{ 
			 
			$sql_s="SELECT * FROM products 
				WHERE id_product={$id}"; 
			$query_s=mysql_query($sql_s); 
			if(mysql_num_rows($query_s)!=0){ 
				$row_s=mysql_fetch_array($query_s); 
				 
				$_SESSION['cart'][$row_s['id_product']]=array( 
						"quantity" => 1, 
						"price" => $row_s['price'] 
					); 
				 
				 
			}else{ 
				 
				$message="This product id it's invalid!"; 
				 
			} 
			 
		} 
		 
	} 
 
?> 
	<h1>Product List</h1> 
	<?php 
		if(isset($message)){ 
			echo "<h2>$message</h2>"; 
		} 
	?> 
	<table> 
		<tr> 
			<th>Name</th> 
			<th>Description</th> 
			<th>Price</th> 
			<th>Action</th> 
		</tr> 
		 
		<?php 
		 
			$sql="SELECT * FROM products ORDER BY name ASC"; 
			$query=mysql_query($sql); 
			 
			while ($row=mysql_fetch_array($query)) { 
				 
		?> 
			<tr> 
			    <td><?php echo $row['name'] ?></td> 
			    <td><?php echo $row['description'] ?></td> 
			    <td><?php echo $row['price'] ?>$</td> 
			    <td><a href="index.php?page=products&action=add&id=<?php echo $row['id_product'] ?>">Add to cart</a></td> 
			</tr> 
		<?php 
				 
			} 
		 
		?> 
		 
	</table>

Here's the error message if the id of the product is invalid



Step 8

Let's go back to the index.php and build the sidebar. Add the following code:

 
	<h1>Cart</h1> 
	<?php 
	 
		if(isset($_SESSION['cart'])){ 
			 
			$sql="SELECT * FROM products WHERE id_product IN ("; 
			 
			foreach($_SESSION['cart'] as $id => $value) { 
				$sql.=$id.","; 
			} 
			 
			$sql=substr($sql, 0, -1).") ORDER BY name ASC"; 
			$query=mysql_query($sql); 
			while($row=mysql_fetch_array($query)){ 
				 
			?> 
				<p><?php echo $row['name'] ?> x <?php echo $_SESSION['cart'][$row['id_product']]['quantity'] ?></p> 
			<?php 
				 
			} 
		?> 
			<hr /> 
			<a href="index.php?page=cart">Go to cart</a> 
		<?php 
			 
		}else{ 
			 
			echo "<p>Your Cart is empty. Please add some products.</p>"; 
			 
		} 
	 
	?>
  1. First we check if the session cart is set. If it's not, we display the message, alerting the user that the cart is empty.
  2. Next we make a mysql SELECT, but we're selecting only the products that exists in the session too. To accomplish this, we use the foreach function. So we are looping through the session and are adding the product id to the SELECT. Next, we are using the substr function to remove the last comma from the SELECT.
  3. In the end we output the data to the browser.

Take a look at the pictures below:



Since the index.php is a template for all the files, the sidebar will be visible in the cart.php too. Ain't that cool?!


Step 9

Finally, open cart.php and start by typing the following code:

 
<h1>View cart</h1> 
<a href="index.php?page=products">Go back to products page</a> 
<form method="post" action="index.php?page=cart"> 
     
	<table> 
	     
		<tr> 
		    <th>Name</th> 
		    <th>Quantity</th> 
		    <th>Price</th> 
		    <th>Items Price</th> 
		</tr> 
		 
		<?php 
		 
			$sql="SELECT * FROM products WHERE id_product IN ("; 
					 
					foreach($_SESSION['cart'] as $id => $value) { 
						$sql.=$id.","; 
					} 
					 
					$sql=substr($sql, 0, -1).") ORDER BY name ASC"; 
					$query=mysql_query($sql); 
					$totalprice=0; 
					while($row=mysql_fetch_array($query)){ 
						$subtotal=$_SESSION['cart'][$row['id_product']]['quantity']*$row['price']; 
						$totalprice+=$subtotal; 
					?> 
						<tr> 
						    <td><?php echo $row['name'] ?></td> 
						    <td><input type="text" name="quantity[<?php echo $row['id_product'] ?>]" size="5" value="<?php echo $_SESSION['cart'][$row['id_product']]['quantity'] ?>" /></td> 
						    <td><?php echo $row['price'] ?>$</td> 
						    <td><?php echo $_SESSION['cart'][$row['id_product']]['quantity']*$row['price'] ?>$</td> 
						</tr> 
					<?php 
						 
					} 
		?> 
					<tr> 
					    <td colspan="4">Total Price: <?php echo $totalprice ?></td> 
					</tr> 
		 
	</table> 
	<br /> 
	<button type="submit" name="submit">Update Cart</button> 
</form> 
<br /> 
<p>To remove an item, set it's quantity to 0. </p>

The code is similar to the one from index.php and products.php, so I'm not going to explain everything again. You should notice that instead of displaying the quantity in a form, now it's displayed in an input box (so that we can change the quantity). Also the table is wraped in a form tag.To get the total price of the items we multiply the quantity of the specific product(from the session) id with it's price. This is done in each loop.

NOTE: The input is an array, the key is the id of the product, and the quantity is the quantity value.



Step 10

The last step we need to do is to make the form work. So add this code to the top of the cart.php page.

 
if(isset($_POST['submit'])){ 
 
foreach($_POST['quantity'] as $key => $val) { 
	if($val==0) { 
		unset($_SESSION['cart'][$key]); 
	}else{ 
		$_SESSION['cart'][$key]['quantity']=$val; 
	} 
} 
 
}
  1. First we check if the form was submitted. If it was submitted and the value of the input was zero, we unset that session.
  2. If the value is any other value, we set the quantity to that value instead.

Here is the complete cart.php

 
	<?php 
 
	if(isset($_POST['submit'])){ 
		 
		foreach($_POST['quantity'] as $key => $val) { 
			if($val==0) { 
				unset($_SESSION['cart'][$key]); 
			}else{ 
				$_SESSION['cart'][$key]['quantity']=$val; 
			} 
		} 
		 
	} 
 
?> 
 
<h1>View cart</h1> 
<a href="index.php?page=products">Go back to the products page.</a> 
<form method="post" action="index.php?page=cart"> 
     
	<table> 
	     
		<tr> 
		    <th>Name</th> 
		    <th>Quantity</th> 
		    <th>Price</th> 
		    <th>Items Price</th> 
		</tr> 
		 
		<?php 
		 
			$sql="SELECT * FROM products WHERE id_product IN ("; 
					 
					foreach($_SESSION['cart'] as $id => $value) { 
						$sql.=$id.","; 
					} 
					 
					$sql=substr($sql, 0, -1).") ORDER BY name ASC"; 
					$query=mysql_query($sql); 
					$totalprice=0; 
					while($row=mysql_fetch_array($query)){ 
						$subtotal=$_SESSION['cart'][$row['id_product']]['quantity']*$row['price']; 
						$totalprice+=$subtotal; 
					?> 
						<tr> 
						    <td><?php echo $row['name'] ?></td> 
						    <td><input type="text" name="quantity[<?php echo $row['id_product'] ?>]" size="5" value="<?php echo $_SESSION['cart'][$row['id_product']]['quantity'] ?>" /></td> 
						    <td><?php echo $row['price'] ?>$</td> 
						    <td><?php echo $_SESSION['cart'][$row['id_product']]['quantity']*$row['price'] ?>$</td> 
						</tr> 
					<?php 
						 
					} 
		?> 
					<tr> 
					    <td colspan="4">Total Price: <?php echo $totalprice ?></td> 
					</tr> 
		 
	</table> 
	<br /> 
	<button type="submit" name="submit">Update Cart</button> 
</form> 
<br /> 
<p>To remove an item set its quantity to 0. </p>

I hope you enjoyed this tutorial. If you have any questions, be sure to watch the more in depth video tutorial!

Related Posts
  • Code
    Theme Development
    Creating a WordPress Theme from Static HTML: Creating an Archive TemplateCreating wordpress theme from html 400
    If you've been working your way through this series, you now have a functioning theme with two page templates. The steps I've demonstrated to this point are: preparing your markup for WordPress converting your HTML to PHP and splitting your file into template files editing the stylesheet and uploading your theme to WordPress adding a loop to your index file adding meta tags, the wp_head hook and the site title and description to your header file adding a navigation menu adding widget areas to the header and sidebar adding widget areas, a colophon and the wp_footer hook to the footer file creating template files for static pages. Read More…
  • Code
    PHP
    Creating a Photo Tag Wall With Twilio Picture Messaging & PHPProcedural to oop php retina preview
    Twilio's recently announced Picture Messaging has vastly opened up what we can do with text messaging, now we can attach photos to our text messages and have them get used in different ways. In our case, we are going to build a Photo Tag Wall, which will contain photos linked to tags that will be displayed on a website.Read More…
  • Web Design
    Email
    Creating a Simple Responsive HTML EmailEmail new rwd thumb
    In this tutorial I will show you how to create a simple responsive HTML email which will work in every email client, including all the new smartphone mail clients and apps. It uses minimal media queries and a fluid width approach to ensure maximum compatibility.Read More…
  • Code
    Theme Development
    Creating a WordPress Theme From Static HTML: Creating Template FilesCreating wordpress theme from html 400
    In the first part of this series, I showed you how to prepare your HTML and CSS files for WordPress, ensuring the structure would work, the code was valid and that the correct classes were being used. In this tutorial you'll learn how to take your index.html file and split it up into a set of template files for use by WordPress.Read More…
  • Code
    JavaScript & AJAX
    Working With IndexedDB - Part 2Indexeddb retina preview
    Welcome to the second part of my IndexedDB article. I strongly recommend reading the first article in this series, as I'll be assuming you are familiar with all the concepts covered so far. In this article, we're going to wrap up the CRUD aspects we didn't finish before (specifically updating and deleting content), and then demonstrate a real world application that we will use to demonstrate other concepts in the final article.Read More…
  • Code
    HTML & CSS
    Pure: What, Why, & How?Pure retina preview
    This tutorial will introduce you to Pure, a CSS library made of small modules, that can help you in writing completely responsive layouts, in a very fast and easy way. Along the way, I'll guide you through the creation of a simple page in order to highlight how you can use some of the library's components.Read More…