Building a simple PHP shopping cart

Nov 21 2005

Update 21/11: I’ve added a demo and downloadable .zip file at the end of the article.

Update 07/12: Thanks to Greg and Rob Shan Lone for spotting a bug in the cart update code – I’ve now fixed this and updated the demo and .zip file; thanks guys!

One of the most common requirements any web designer/developer will come across is likely to be that of the small business taking its first steps online; a client with an established widget-selling company now wants to move into the national market and sell their widgets to the world.

What they need to do this (apart from a great-looking, functional, usable and accessible website!) is some sort of shopping-cart system to allow their customers to add, remove and update the products they wish to buy.

This article will walk through the simple steps to achieve this, using the server-side language PHP and a MySQL database.

Setting up the database

Let’s take as our example a bookseller. They are not the best-stocked bookseller in the world, having as they do only three titles in stock, but it is enough for our example. Let’s create the database and add some stock:

  1. CREATE TABLE books (
  2. id int(6) unsigned NOT NULL auto_increment,
  3. title varchar(100) NOT NULL default '',
  4. author varchar(100) NOT NULL default '',
  5. price decimal(3,2) NOT NULL default '0.00',
  6. PRIMARY KEY (id)
  7. ) TYPE=MyISAM;
  8.  
  9. INSERT INTO books VALUES (1, 'Where God Went Wrong', 'Oolon Colluphid', '24.99');
  10. INSERT INTO books VALUES (2, 'Some More of God\'s Greatest Mistakes', 'Oolon Colluphid', '17.99');
  11. INSERT INTO books VALUES (3, 'Who Is This God Person Anyway?', 'Oolon Colluphid', '14.99');
  12. Download this code: /code/php-cart-1.txt

Now that step is out of the way, let’s create our shopping cart.

Identify our requirements

The cart we are going to build should be pretty familiar to most internet users. It will provide a means of displaying a message on every page of the site (along the lines of “You have 5 items in your shopping cart”), which when clicked will take the customer to a list of the items in the cart; each item may be removed or have its quantity updated.

As all of our stock details are stored in the database, the only piece of information that we need to store about each customer is the id of each product they have added to their cart. To do this, we are going to use PHP’s built-in session handling capabilities.

Using sessions in PHP

PHP’s session handling is very easy to understand.

To ‘switch it on’, simply add session_start(); at the top of your code; you can then store values (or arrays) in session variables:

$_SESSION['name'] = 'Matthew'; $_SESSION['age'] = 31;

These $_SESSION variables will now be available to any PHP scripts on other pages (as long as you’ve included the session_start(); call first).

A short note on cookies

The default behaviour of PHP sessions is to store the session ID (a long string of numbers and letters that identifies you to the server) as a cookie on your computer; however, even if you have cookies disabled this functionality will still work – PHP will instead append the session ID to each link on the site (in the form ‘mypage.php?PHPSESSID=’) so that it can continue to accurately track visitors from page to page.

Creating the cart

We will store the contents of the shopping cart as a comma-separated list of product ids in a session named (unsurprisingly) ‘cart’ – for example, a cart containing “1,1,3,1,2” has four items; three of product #1, and one each of products #2 and #3.

Firstly, let’s create the code to display the “You have X items…” message on every page:

  1. function writeShoppingCart() {
  2. $cart = $_SESSION['cart'];
  3. if (!$cart) {
  4. return '<p>You have no items in your shopping cart</p>';
  5. } else {
  6. // Parse the cart session variable
  7. $items = explode(',',$cart);
  8. $s = (count($items) > 1) ? 's':'';
  9. return '<p>You have <a href="cart.php">'.count($items).' item'.$s.' in your shopping cart</a></p>';
  10. }
  11. }
  12.  
  13. Download this code: /code/php-cart-2.txt

This function first gets the value of the ‘cart’ session variable into a local variable, mainly to save on typing. If the cart is empty, we return an appropriate message; if not, we use the explode() function to create an array of all the products in the cart, and then count() them and display the result (the $s variable is there to make plurals display correctly).

Now we can display the correct message anywhere on the site:

echo writeShoppingCart();

I hope that made sense; let’s move on to displaying the contents of the cart itself.

Show me the money

The shopping cart page itself (cart.php) can be arrived at in a couple of ways. The user may have clicked on the link created by the writeShoppingCart() function above; or, they may have clicked an ‘Add to cart’ link on a product page.

If it was the latter, we need to intercept that click and update our cart contents before displaying the new list of products – simple enough, as all we need to do is append the id of the clicked product to the ‘cart’ session variable. Our product links are going to look like this:

<a href="cart.php?action=add&id=1">Add to cart</a>

Don’t worry about the ‘action=add’ bit, we’ll get to that later. The id can now be extracted from $_GET[‘id’] and added to our cart:

  1. $cart = $_SESSION['cart'];
  2. if ($cart) {
  3. $cart .= ','.$_GET['id'];
  4. } else {
  5. $cart = $_GET['id'];
  6. }
  7. $_SESSION['cart'] = $cart;
  8. Download this code: /code/php-cart-3.txt

Now, on to the contents of our cart!

Multiple items, one product

As in our example above, it is entirely possible that a customer might have more than one of a certain product in their cart. As we don’t want to list duplicate items when we display the contents, we need to figure out a way to combine any of the same product into one entry (with a corresponding quantity attached).

  1. $cart = $_SESSION['cart'];
  2. if ($cart) {
  3. $items = explode(',',$cart);
  4. $contents = array();
  5. foreach ($items as $item) {
  6. $contents[$item] = (isset($contents[$item])) ? $contents[$item] + 1 : 1;
  7. }
  8. Download this code: /code/php-cart-4.txt

This time, after exploding the list of product ids, we have iterated through them to create a new array named $contents, which consists of key=>value pairs where the key is the product id and the value is the quantity of that product in the shopping cart. So to take our example above, a cart containing “1,1,3,1,2” would become an array where ‘1’=>3, ‘2’=>1, ‘3’=>1.

Now that we have an accurate count of unique products, let’s query the product database for each one and output its details into a table:

  1. $total = 0;
  2. $output[] = '<table>';
  3. foreach ($contents as $id=>$qty) {
  4. $sql = 'SELECT * FROM books WHERE id = '.$id;
  5. $result = $db->query($sql);
  6. $row = $result->fetch();
  7. extract($row);
  8. $output[] = '<tr>';
  9. $output[] = '<td><a href="cart.php?action=delete&id='.$id.'" class="r">Remove</a></td>';
  10. $output[] = '<td>'.$title.' by '.$author.'</td>';
  11. $output[] = '<td>&pound;'.$price.'</td>';
  12. $output[] = '<td><input type="text" name="qty'.$id.'" value="'.$qty.'" size="3" maxlength="3" /></td>';
  13. $output[] = '<td>&pound;'.($price * $qty).'</td>';
  14. $total += $price * $qty;
  15. $output[] = '</tr>';
  16. }
  17. $output[] = '</table>';
  18. $output[] = '<p>Grand total: &pound;'.$total.'</p>';
  19.  
  20. Download this code: /code/php-cart-5.txt

(*Note*: I’m using a PHP class to handle my database connections, so your code may need to be slightly different).

Pretty simple stuff – we iterate through the new $contents array and query the database for each product id. Then we output the relevant details for each product; title, author and price, and at the bottom we show the grand total for the order. For each item, we’ve also included a link to remove the item from the cart, a textbox containing the current quantity of that item, and a total price (obviously this will only differ from the base price if the quantity is not 1).

The reason I’m using $output[] = ... is that I am buffering the output into an array to print to the screen later.

So far so good – now how about removing products from the cart?

Deleting a product

As shown above, the link to delete a product from the cart follows the same format as the ‘add a product’ link:

<a href="cart.php?action=delete&id=1">Remove</a>

Let’s expand on the code from earlier by adding a switch() statement to handle the different things that might happen to our cart:

  1. $cart = $_SESSION['cart'];
  2. $action = $_GET['action'];
  3. switch ($action) {
  4. case 'add':
  5. if ($cart) {
  6. $cart .= ','.$_GET['id'];
  7. } else {
  8. $cart = $_GET['id'];
  9. }
  10. break;
  11. case 'delete':
  12. if ($cart) {
  13. $items = explode(',',$cart);
  14. $newcart = '';
  15. foreach ($items as $item) {
  16. if ($_GET['id'] != $item) {
  17. if ($newcart != '') {
  18. $newcart .= ','.$item;
  19. } else {
  20. $newcart = $item;
  21. }
  22. }
  23. }
  24. $cart = $newcart;
  25. }
  26. break;
  27. }
  28. $_SESSION['cart'] = $cart;
  29. Download this code: /code/php-cart-6.txt

The new ‘delete’ case iterates through the ‘cart’ session, looking for any product ids that AREN’T the one we’re deleting, and adding them to a temporary variable called $newcart. When it’s finished, it puts the revised cart contents back into $cart.

Updating a product

Lastly, we are going to allow customers to update the contents of their shopping cart by manually changing the value in the quantity box for each product.

To make this work, we’ll wrap the shopping cart table in a <form> so that the ‘update cart’ button will submit the form:

  1. $output[] = '<form action="cart.php?action=update" method="post" id="cart">';
  2. $output[] = '<table>';
  3. foreach ($contents as $id=>$qty) {
  4. $sql = 'SELECT * FROM books WHERE id = '.$id;
  5. $result = $db->query($sql);
  6. $row = $result->fetch();
  7. extract($row);
  8. $output[] = '<tr>';
  9. $output[] = '<td><a href="cart.php?action=delete&id='.$id.'" class="r">Remove</a></td>';
  10. $output[] = '<td>'.$title.' by '.$author.'</td>';
  11. $output[] = '<td>&pound;'.$price.'</td>';
  12. $output[] = '<td><input type="text" name="qty'.$id.'" value="'.$qty.'" size="3" maxlength="3" /></td>';
  13. $output[] = '<td>&pound;'.($price * $qty).'</td>';
  14. $total += $price * $qty;
  15. $output[] = '</tr>';
  16. }
  17. $output[] = '</table>';
  18. $output[] = '<p>Grand total: &pound;'.$total.'</p>';
  19. $output[] = '<div><button type="submit">Update cart</button></div>';
  20. $output[] = '</form>';
  21. Download this code: /code/php-cart-7.txt

Note that, even though the form uses the POST method, its action includes a GET variable, “action=update”. Again, we can expand our previous code to process any quantity updates:

  1. case 'update':
  2. if ($cart) {
  3. $newcart = '';
  4. foreach ($_POST as $key=>$value) {
  5. if (stristr($key,'qty')) {
  6. $id = str_replace('qty','',$key);
  7. $items = ($newcart != '') ? explode(',',$newcart) : explode(',',$cart);
  8. $newcart = '';
  9. foreach ($items as $item) {
  10. if ($id != $item) {
  11. if ($newcart != '') {
  12. $newcart .= ','.$item;
  13. } else {
  14. $newcart = $item;
  15. }
  16. }
  17. }
  18. for ($i=1;$i<=$value;$i++) {
  19. if ($newcart != '') {
  20. $newcart .= ','.$id;
  21. } else {
  22. $newcart = $id;
  23. }
  24. }
  25. }
  26. }
  27. }
  28. $cart = $newcart;
  29. break;
  30.  
  31. Download this code: /code/php-cart-8.txt

This looks quite complicated, but it’s fairly straightforward; we interrogate the contents of the $_POST array (which holds all our quantity values) and extract the relevant id and value pairs. For each product, we then delete all the existing instances of it, and re-insert the new quantity.

There are a number of ways this could have been done – for example, by counting the existing number of each product present in the cart and figuring out whether we needed to add or remove items – but this seemed the easiest way to process the quantity updates.

Summary

And that’s about it! A functional and easy shopping cart script – here’s the final function to display the contents of the cart:

  1. function showCart() {
  2. $cart = $_SESSION['cart'];
  3. if ($cart) {
  4. $items = explode(',',$cart);
  5. $contents = array();
  6. foreach ($items as $item) {
  7. $contents[$item] = (isset($contents[$item])) ? $contents[$item] + 1 : 1;
  8. }
  9. $output[] = '<form action="cart.php?action=update" method="post" id="cart">';
  10. $output[] = '<table>';
  11. foreach ($contents as $id=>$qty) {
  12. $sql = 'SELECT * FROM books WHERE id = '.$id;
  13. $result = $db->query($sql);
  14. $row = $result->fetch();
  15. extract($row);
  16. $output[] = '<tr>';
  17. $output[] = '<td><a href="cart.php?action=delete&id='.$id.'" class="r">Remove</a></td>';
  18. $output[] = '<td>'.$title.' by '.$author.'</td>';
  19. $output[] = '<td>&pound;'.$price.'</td>';
  20. $output[] = '<td><input type="text" name="qty'.$id.'" value="'.$qty.'" size="3" maxlength="3" /></td>';
  21. $output[] = '<td>&pound;'.($price * $qty).'</td>';
  22. $total += $price * $qty;
  23. $output[] = '</tr>';
  24. }
  25. $output[] = '</table>';
  26. $output[] = '<p>Grand total: &pound;'.$total.'</p>';
  27. $output[] = '<div><button type="submit">Update cart</button></div>';
  28. $output[] = '</form>';
  29. } else {
  30. $output[] = '<p>You shopping cart is empty.</p>';
  31. }
  32. return join('',$output);
  33. }
  34. Download this code: /code/php-cart-9.txt

Note that if the cart is empty, a suitable message is displayed.

A working demo can be seen (excuse the lack of design!), or please feel free to download a .zip of all the files – any questions, comments or suggestions on how the code could be improved gratefully received.

Filed under: PHP, MySQL.

Technorati tags:

Digg this article

Bookmark this article with del.icio.us

Previously: Today I have mostly been learnin'...

Next: Random song lyrics: Update


Comments

Matthijs
3169 days ago
Nice article! A good explanation for how the basics of a shopping cart work. That’ll help us on our way. Thanks.
#1
Christian Montoya
3166 days ago
Awesome. I bookmarked this for later.
#2
Hamish Keith
3161 days ago
Very very good – prob the best i have seen on the web
#3
Andrew
3157 days ago
Thank you so much for this tutorial. It was exactly what I’d been looking for for some time. Great design as well. Beautifully done.
#4
Greg Hamilton
3157 days ago
First of all wicked article, very helpful. Whats the best way to attempt the checkout ? Thanks
#5
Matthew Pennell
3156 days ago
Greg: Funny you should ask that, as I wrote an article that kind of touches on the subject – it is specific to Textpattern, but there is a section on ‘Shopping Integration’ that covers using PayPal to handle payment.

As we’re doing the shoppng cart bit ourselves, we could use PayPal’s new API to simply send the payment details and receive back the response (or whatever other payment processor we’re using).
#6
Greg Hamilton
3156 days ago
Hey Matt thanks for the with the checkout help, quick question about the update function..when you try to update an id that isn’t qty1 it doesnt update…not sure if I messed up the demo file or not :( thanks
#7
Greg Hamilton
3156 days ago
Sorry Matt I mean if you have, lets say two products in yer cart and you try to update the top one it doesnt, but the bottom one will. I think it does it in the demo as well….thanks bud
#8
Matthew Pennell
3155 days ago
Thanks, Greg – I’ve fixed the problem and updated the demo and .zip.
#9
Greg Hamilton
3153 days ago
Hey again Matt
Quick question about quantities, is ti possible to add a function that also allows the user to add quantities inside the product view before adding to cart. Thanks bud
#10
Matthew Pennell
3153 days ago
It would be very easy, Greg, although I don’t have time to do it right now – perhaps a later expansion, unless you want to add it in and publish your changes?
#11
Greg Hamilton
3153 days ago
Ya I’m gonna give it a go. I’ll publish when I get it all set to go.
#12
Andrew
3151 days ago
Hi,

Thanks for the tutorial!

i have changed the cart.php page a little. on the cart.php page, if the user clicks re-fresh, an item is added to the the cart as the ID ifor the product is stored in the querystring. its easily fixed.

Just a heads up for some.

Once again thanks for the demo!
#13
Viktor
3148 days ago
Great tutorial. Most tutorials takes too many steps at the same time so you only end up comfused, but this is vert easy to follow and understand.
#14
hidayat
3131 days ago
Good job boss
it’s nice tutorial ,too nice
#15
Franco
3130 days ago
Hi Matthew,
I test your script
but when i add to cart
this is message page:
Please check quantities…
You shopping cart is empty
I don’t see any product choice.
Can you help me?

Regards and happy New year
Franco
#16
Matthew Pennell
3129 days ago
Hi Franco – I’d need a bit more information to work out what might be wrong; the first thing to try though would be to echo the $id and $cart variables as the code progresses through the ‘add’ routine to see what is happening.
#17
The Illumidigerati
3122 days ago
Matt, does this cart form allow enough security for actual business transactions in the form of moneyorder/personal check? I’ll be webmastering my girlfriends home business and starting out neither of us are really keen on dealing with credit or any online payment ventures, i.e. paypal. Is there a reason for anything more secure when moneyorders/personal checks are the only payment methods since only user information will be logged, not CC info or bank account info?
#18
Matthew Pennell
3122 days ago
This cart script doesn’t handle any kind of payment; it is only for keeping track of what is in the shopping cart.
#19
dreamer85
3122 days ago
good tutorial well done
if it explaines how to display image with the products will be greate tutorial
take care
#20
Momotaro
3112 days ago
Excellent tutorial.
I’d like to know how to display the result in a Form that could then be saved to .csv file server-side? Ultimately, even send me an email when order Form was submited. The tutorials I’ve come across in past were too full of tech-speak that I couldn’t understand.
#21
Aneurin
3107 days ago
Thank You for the tutorial…
i was wondering if i could add product option to this shopping cart..eg. same item(same product id) but different options (size,colour)...i would appreciate some ideas…thanks in advance…
#22
Matthew Pennell
3107 days ago
Aneurin: Yes, that’s certainly an option; the project that I developed this cart code for does just that.

I used certain characters to split the product that was added to the cart, so to take your example of something with a certain size and colour, I would store the sizes and colours in their own tables in the database, then add products in the format “123c6s3”, which would translate as “Product #123, colour #6, size #3”.

The show-cart page would then lookup that colour and size from the table as part of the SQL statement and display the correct description of the product.
#23
Matthew Pennell
3107 days ago
Momotaro: Sending an email when the order is submitted would be pretty simple – the PHP mail() function covers that in detail.
#24
Aneurin
3107 days ago
Thank You very much…...
#25
momotaro
3105 days ago
Thanks for the link
#26
junwei
3096 days ago
nice! It help me alot, u mind adding add to cart and login function . thank
#27
Cormac
3096 days ago
are there anyother api’s that could be intergrated fairly easily with this shopping cart other than PayPal’s ?
#28
Matthew Pennell
3095 days ago
Cormac: There are quite a few online payment mechanisms that are as easy to integrate with as PayPal. WorldPay is probably the next best known one, but there are plenty around.
#29
Matt Cooper
3089 days ago
Nice code, and I very much like your website too, very fresh design. One disappointment (only a small one!) is that you haven’t provided further code for a checkout…is this on the cards? Good luck…
#30
Tan
3087 days ago
Great Demo, the best on the web!
I have one problem, same as franco above, I select add item and it displays check quantities on the cart page, with no items passed through. I have had a look over every page to no avail, would it be a function issue? It passes the id through the url but does not display it.
#31
James
3082 days ago
Hi Matt,

I’m new to all this and am pulling my hair out! – it just won’t work for me – getting messages such as:

Query failed: Unknown column ‘Array’ in ‘where clause’ SQL: SELECT * FROM book WHERE id = Array

or…

Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result

or…

Warning: mysql_num_rows(): supplied argument is not a valid MySQL

Where am I going wrong – from the other comments it seems to be pretty easy so it must be something I’m doing wrong!

Thanks for any help – very frstrated at the moment!

James
#32
Matthew Pennell
3082 days ago
James: That sounds as if the id is not being passed through in the querystring correctly. Check that you have populated the database correctly and have configured your database connection information properly.
#33
tan
3081 days ago
Just me again, why would it not display in the cart. Please note above note.
#34
Matthew Pennell
3081 days ago
Tan: It sounds as if the id variable in the querystring is not being picked up by the code (php-cart-3 in the code above) and added to the cart.

You could try adding a loop through all the items in the GET collection:
foreach ($_GET as $key => $value) {
  echo $key . ’ contains ’ . $value . '<br />';
}
That will list everything all the variables in the querystring; if nothing is there, it may be that you’ve changed the form method to “post” instead of “get”? Or possibly you're using a very old version of PHP that doesn't support $_GET - you could try the above code with $HTTP_GET_VARS instead; if that works you'll have to change all instances of $_GET to $HTTP_GET_VARS (or upgrade to a host supporting a more modern version of PHP!)
#35
CHiNo4ReaL
3079 days ago
Nice tutorial, I’m gonna use it, but I have a question, is it possible to create catogory’s,
#36
Matthew Pennell
3079 days ago
Chino: Do you mean in the products listings, or in the cart session variable?

It depends how your database is set up whether you’d need any additional work to cope with categories.
#37
G
3079 days ago
Hello,

I have installed your cart on my website, but I have a problem. When I navigate between cart.php and index.php it appears this error message:
“Warning: session_start(): Cannot send session cache limiter – headers already sent (output started at ….global.inc.php:9) in cart.php on line 9”
“Warning: session_start(): Cannot send session cache limiter – headers already sent ”...
Can you please help me to solve it out?
Regards,
G.
#38
CHiNo4ReaL
3078 days ago
@Matthew

Yes, because i’m creating a webshop, with carparts, so there are a few catorgies, like exterior, frontbumpers, rims etc.
#39
CHiNo4ReaL
3078 days ago
Oh and another question, How can I finish the order?
#40
Matthew Pennell
3078 days ago
G: The session_start() command has to appear in the code before any output has been sent to the browser. As your error says, there is output being sent at line 9 of global.inc.php – you must have changed the source files, as my originals only have database connection variables in that file.
#41
Matthew Pennell
3078 days ago
Chino: Bear in mind that the id of the product that is held in the cart doesn’t have to include any reference to the category it is in.

You just have to alter the products database to include a category field; you can then use that when listing products, but just use the product id to hold it in the cart.

To finish the order, you’re going to have to decide what you want to do with it – either have it saved to a database, emailed to you, or processed by an online payment processor like PayPal. That’s beyond the scope of this tutorial, though.
#42
CHiNo4ReaL
3077 days ago
Ok, Do you have an example for the catorgyfield in the database?
#43
jatty5
3077 days ago
Hi all, I am new to this php and am trying to buid a shopping cart for my business myself. I have installed easyphp which has given me apache mysql and php, and am trying to work through this tutorial which I think is excellent for somebody like me a total novice! I have managed to create the database succesfully by copy the complete script and putting it through phpmyadmin. I tried to download the complete zip files, but where do i put them and how on earth do i set the database connection files up. Please help as I am getting alittle lost. I have also downloaded each script but agian where does it go, i know it would be in the WWW directory of my easyphp folder. Please help
#44
Matthew Pennell
3076 days ago
Chino: Just add a category field into your database using whatever MySQL admin tool you’re using.
#45
Matthew Pennell
3076 days ago
jatty5: If you have downloaded the zip you don’t need the individual scripts; just unpack the zip file to a folder under your www directory (e.g. “cart”). The database connection settings are in inc/global.inc.php if you need to change them, but if you’re running it locally the settings should be fine.

Then visit http://localhost/cart/ and it should all be working (you may have to start the PHP and MySQL services, depending on the package you are using).
#46
jatty5
3076 days ago
Hi Mathew, thanks for your swift reply, i have done what you said but still get the following reply:

I take it it has something to do with the database i created the database under phpmyadmin and called the database wtchproject and then run your script under that which created your tables under this database.

What do i change in the gobal file and is it possible for you to show where i can make those changes if possible.

Notice: Could not select database in c:\program files\easyphp1-8\www\cart-demo\inc\mysql.class.php on line 80

Warning: session_start(): Cannot send session cookie – headers already sent by (output started at c:\program files\easyphp1-8\www\cart-demo\inc\mysql.class.php:80) in c:\program files\easyphp1-8\www\cart-demo\index.php on line 9

Warning: session_start(): Cannot send session cache limiter – headers already sent (output started at c:\program files\easyphp1-8\www\cart-demo\inc\mysql.class.php:80) in c:\program files\easyphp1-8\www\cart-demo\index.php on line 9
Your Shopping Cart

Notice: Undefined index: cart in c:\program files\easyphp1-8\www\cart-demo\inc\functions.inc.php on line 3

You have no items in your shopping cart
Books In Our Store

Notice: Query failed: No database selected SQL: SELECT * FROM books ORDER BY id in c:\program files\easyphp1-8\www\cart-demo\inc\mysql.class.php on line 109

Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in c:\program files\easyphp1-8\www\cart-demo\inc\mysql.class.php on line 151

Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in c:\program files\easyphp1-8\www\cart-demo\inc\mysql.class.php on line 167
#47
ScopAL
3076 days ago
Notice: Undefined index: cart in z:\home\cart\www\inc\functions.inc.php on line 3

You have no items in your shopping cart

:((((
#48
CHiNo4ReaL
3076 days ago
Jatty5
I think that you have selected the wrong database, your database is called wtchprojec, but in the script its selecting books
#49
Matthew Pennell
3076 days ago
jatty5: I would suggest that if you’re trying to learn to use PHP/MySQL, it would be a good idea to learn all about creating database connections, but here is how to fix your problem:

In global.inc.php, you have four variables that are used to create the database connection:

$host = ‘localhost’;
$user = ‘root’;
$pass = ‘’;
$name = ‘’;

These correspond to your host name (usually ‘localhost’), the username and password you are using, and the name of your database.

So in your case, just change the last line to $name=’wtchproject’; and the database connection class object will then be pointing at your database.
#50
CHiNo4ReaL
3074 days ago
If I want the order mailed to me, how can I do that?
I have tried to do that, but i cant find any good ones, can u help me?
#51
Matthew Pennell
3074 days ago
I suppose you’d have to build in some data capture for the customer’s details, and then use mail() to send everything.

I’m not building the whole site for you, though..! ;)
#52
CHiNo4ReaL
3073 days ago
ok, thanks anyway
#53
Greg Hamilton
3071 days ago
Hey again Matt, what are your feelings on using cookies instead of sessions to remember the items that are in the shopping cart, do you think its necessary at all ?
#54
Matthew Pennell
3071 days ago
Greg: The benefit would obviously be that you would be able to leave the site and come back to the same basket; an approach using both sessions and cookies would probably be a good idea (with a fairly short expiration period).
#55
Juilius
3070 days ago
Hi I am having problems with the cart.php, whenever I hit the refresh button it adds another quantity to the cart? Any ideas?
Oh by the way, great, great example!
#56
Matthew Pennell
3069 days ago
Juilius: Yes, refreshing the page will add another item to the cart due to its use of the querystring ($_GET collection) to handle addition.

You can get around it by adding an extra session variable and storing the last item added and the time it was added, then checking against that to see if it is a repeated entry within a certain timeframe.
#57
Steven
3044 days ago
I’ll be messing around with this on XAMPP soon! I’m a bit of a PHP beginner but I thinks it’s important to dive in at the deep end!
#58
Steven
3044 days ago
I’ll be messing around with this on XAMPP soon! I’m a bit of a PHP beginner but I thinks it’s important to dive in at the deep end!

PS. Edited to ask, does a shopping cart system like this have to be bolted onto a dynamic website or can I add it to static product pages?
#59
Matthew Pennell
3044 days ago
Steven: I’m not sure how you’d use it with static pages, as it relies on a database of product details – I suppose you could copy your static data into the database, but if you’re doing that you may as well be using the database to output your product info as well!
#60
Fred
3028 days ago
I’m just curious, since this code connect to the db and all. Is this vulnerable to sql injection at all?

Can users modify the input variables or the session cookie to inject special characters that could cause buffer overflow in the SQL sequence?

I don’ recall seeing anywhere that inputs are scrubbed, but I could be wrong or the way the code is written, input scrubbing might be a non-issue.

Any confirmation on this?
#61
Matthew Pennell
3027 days ago
Fred: You are correct that if you wanted to use this in a commercial setting it would be a good idea to add some validation of the session data when it is read to output the contents of the cart. This could be as simple as using preg_match to check that the ID of the product is numeric.
#62
Fred
3027 days ago
This was some amazingly great cart code which gave me a good jump on what I wanted to create. Thanks Matt.

I did add some basic sanitization code to keep the db safe from SQL injects. You can take from the following.

I added a sanitization function and then called it on certain variable inputs used in the cart program:

function sanitize_system_string($string, $min=’’, $max=’’) {
$pattern = ’/(;|\||`|>| $max)))
return FALSE;
return $string;
}

// these occur in various places
sanitize_system_string($_GET[‘id’],1,50)
$cart = sanitize_system_string($_SESSION[‘cart’]);
$action = sanitize_system_string($_GET[‘action’],1,50);

// assigned right underneath the update switch foreach loop
$key = sanitize_system_string($key,1,50);
#63
Alex
3027 days ago
Thanx for the code Fred very helpful…
#64
Fred
3026 days ago
Sorry the sanitize_system_string function got partially truncated by the comment submit form. The other examples of variable sanitization remained in tact though.

Anyway, folks can get the point. Find a sanitization function, insert it in the functions php document and then employ it throughout the cart code as needed.

I identified several good places in the last post :)

I love this cart code matt provided! It has provided me the basis to do some wonders with it!
#65
Ella
3025 days ago
Hi There,
I am fairly new to php etc and am trying to do a shopping cart as part of my final project for my degree. I am getting an error when I click the add to cart link it goes through to the cart page but has the following error:
Parse error: parse error in c:\LocalUser\fashuti\public_html\cart.php on line 174
it is erroring on the last line of code on the page which is obciously not the problem. I have adapted the code on your size so that i can distinguish by id, size and colour. My id’s are both letter and charactger based. I can understand all of the code apart from one line which confuses me and I wonder if it could relate to that?
It seems you are comparing qty which is created here to the id?

foreach ($contents as $id=>$qty) {

I wondered if this could be my problem?
I will post my cart code below:

Hi There,
I am fairly new to php etc and am trying to do a shopping cart as part of my final project for my degree. I am getting an error when I click the add to cart link it goes through to the cart page but has the following error:
Parse error: parse error in c:\LocalUser\fashuti\public_html\cart.php on line 174
it is erroring on the last line of code on the page which is obciously not the problem. I have adapted the code on your size so that i can distinguish by id, size and colour. My id’s are both letter and charactger based. I can understand all of the code apart from one line which confuses me and I wonder if it could relate to that?
It seems you are comparing qty which is created here to the id?

foreach ($contents as $id=>$qty) {

I wondered if this could be my problem?
I will post my cart code below:

$total = 0;
$output[] = ‘’;

$conn=odbc_connect(‘danum_fashu’,’’,’’);
foreach ($contents as $id=>$qty) {
$sql = ‘SELECT * FROM products, product_line WHERE products.product_id = ’.$id.’ AND products.product_id = product_line.product_id AND product_line.product_size= ’.$sz.’ AND product_line.product_colour = ’.$col;
$rs=odbc_exec($conn,$sql);

$pid=odbc_result($rs,”product_line.product_id”);
$size=odbc_result($rs,”product_line.product_size”);
$name=odbc_result($rs,”products.product_name”);
$colour=odbc_result($rs,”product_line.product_colour”);
$cost=odbc_result($rs,”products.product_costprice”);
$endcost = number_format($cost * 2.6, 2, ’.’, ’,’);

$output[] = ‘’;
$output[] = ‘’.$pid.’ by ’.$name.’’;
$output[] = ‘’.$size.’ ’.$colour.’’;
$output[] = ’£’.$endcost.’’;
$output[] = ‘’;
$output[] = ’£’.($endcost * $qty).’’;
$output[] = ‘Remove’;
$total += $endcost * $qty;
$output[] = ‘’;

}
$output[] = ‘’;
$output[] = ‘Grand total: £’.$total.’’;
odbc_close($conn);

Any help would be gratefully recieved
#66
Matthew Pennell
3025 days ago
Usually if a script throws an error on the very last line it is due to an unclosed bracket somewhere. I can’t see anything obvious in the code you posted; maybe check the rest of that page to see if you have left a bracket open?
#67
Ella
3025 days ago
Ok ive picked it all apart and i think i now know the problem but am unsure of how to fix it.
Like I said I have adapted your code to pass through the id,colour and size of a product. do on the product page the add to cart link is as follows:

echo ‘Add to cart’;

and then when it goes into cart i need these three values for my select statement so that io retrieve the correct record and this is what i have been coding:

$sql = ‘SELECT * FROM products, product_line WHERE products.product_id = ’.$id.’ AND products.product_id = product_line.product_id AND product_line.product_size= ’.$sz.’ AND product_line.product_colour = ’.$col;

Is that correct what i mean is are these variable available to me once i have used this code?

$cart = $_SESSION[‘cart’];
if ($cart) {
$cart .= ’,’.$_GET[‘id’].$_GET[‘sz’].$_GET[‘col’];
} else {
$cart = $_GET[‘id’].$_GET[‘sz’].$_GET[‘col’];
}
$_SESSION[‘cart’] = $cart;

The other thing is if i cannot do this i am not sure how to distinguish one form the other as they can all vary in length.

Thank you for your quick response.
#68
Ella
3025 days ago
sorry my pad add to cart link is as follows:

Add to cart
#69
Ella
3025 days ago
sorry my add to cart link is as follows:

Add to cart
#70
Ella
3025 days ago
sorry my add to cart link is as follows:
I have cut the and opening < so it displays

a href=”shopcart.php?action=add&id=’ . $id .’&sz=’ . $size . ‘&col=’ . $colour .’”>Add to cart
#71
Alex
3025 days ago
... i’m having the same thing…
#72
Ella
3025 days ago
i have found one problem which is that for step 4 php-cart4 there is a closing brace missing from the end of the code:

$cart = $_SESSION[‘cart’];
if ($cart) {
$items = explode(’,’,$cart);
$contents = array();
foreach ($items as $item) {
$contents[$item] = (isset($contents[$item])) ? $contents[$item] + 1 : 1;
}
}
#73
Ella
3025 days ago
having discovered this problem i am now getting an understandable error:

Warning: odbc_exec(): SQL error: [Microsoft][ODBC Microsoft Access Driver] Syntax error (missing operator) in query expression ‘products.product_id = 4THYNGreen12 AND products.product_id = product_line.product_id AND product_line.product_size= AND product_line.product_colour =’., SQL state 37000 in SQLExecDirect in

ass you can see the size colour and id have been grouped together:

products.product_id = 4THYNGreen12

under the value $id and then further into the sql there is no value placed in $colour:

product_line.product_colour =’.,

But i have put in seperate values for the add to basket link:

a href=”shopcart.php?action=add&id=’ . $id .’&sz=’ . $size . ‘&col=’ . $colour .’”>Add to cart
#74
Fred
3025 days ago
I’m having no problems with the base code whatsoever. My cart works like a charm: http://www.feetcore.com/Products/Token-Store.html
#75
Ella
3024 days ago
does anybody else get an error with their select statement for the cart giving warnings when you add a second product?? the warnings are:

Warning: odbc_exec(): SQL error: [Microsoft][ODBC Microsoft Access Driver] Syntax error (missing operator) in query expression ‘product_line.listing_no= AND product_line.product_id = products.product_id’., SQL state 37000 in SQLExecDirect in c:\LocalUser\fashuti\public_html\includes\cart_functions.php on line 41

Warning: odbc_fetch_row(): supplied argument is not a valid ODBC result resource in c:\LocalUser\fashuti\public_html\includes\cart_functions.php on line 43

the php code is:

$conn=odbc_connect(‘danum_fashu’,’’,’’);

$sql =”SELECT * FROM products, product_line WHERE product_line.listing_no= $id AND product_line.product_id = products.product_id”;
$rs=odbc_exec($conn,$sql);

while (odbc_fetch_row($rs))
{

i have echoed out the value in $id and it works fine and the correct outcome is still displayed but these horrid warnings appear, anyone know if i can get rid of them?
#76
FrozenPeas
3021 days ago
Nice script,
but I would make the add to cart a button with a form post.
Otherwise, Google may add items to the cart when spidering your site.
This used to happen with Oscommerce and the buy now button which was not a form action but a href.
#77
Fred
3020 days ago
So maybe the spider engine will make a purchase then.

It should affect any other surfer’s session though if a spider adds an item to it’s own cart.

If I’m correct this cart individualizes content based on individual surfer sessions. Don’t see any harm to the search engine spidering this at all.

I think this cart was very well written aside from the input variable sanitizations
#78
dario
2975 days ago
So far the best design and useful info i’ve seen ever.
I’m the newest of all of you in PHP and built a user registration form with Java, MySQL checkers, actiivation link sent to mail of user
and seeking for Shopping Cart interaction.
I hope to make it work with the session variable i’ve already made.
My best wishes to you Matthew,
thank you for the full working ZIP download.
I hope to find more of your work.
#79
koTo
2962 days ago
Hi ella…I know why does your ID and SIZE and COLOR splitted together..The problem is here..
$cart = $_SESSION[‘cart’];
if ($cart) {
$cart .= ’,’.$_GET[‘id’].$_GET[‘sz’].$_GET[‘col’];
} else {
$cart = $_GET[‘id’].$_GET[‘sz’].$_GET[‘col’];
}
$_SESSION[‘cart’] = $cart;

Look at the 3rd line…where there is:
$cart = $_GET[‘id’].$_GET[‘sz’].$_GET[‘col’];
by thsi code you are splitting this values together.. I will recomend you to do like i did: $cart .= ’,’.$_GET[‘id’].’:’.$_POST[‘color’].’:’.$_POST[‘size’].’:’.$_POST[‘qty’];

Here I have defined: id1:size1:color1:qty1, id2:size2:color2:qty2, etc…
Now i Hope that i helped you :)
#80
wingsfan
2950 days ago
Has anybody actually found a way to get options to work, ie: size, color, etc? Like if somebody wanted to chose a color out of a product drop down.
#81
pez
2945 days ago
Great tutorial! Thanks! I’m new to PHP and am working on a shop for a record label ‘client’ (I say client, but I’m doing it for free!) of mine, and this is a great starting point! Cheers!
#82
charrik
2931 days ago
Hi,
First of all… really a great tutorial. Very helpful

I have just once concern.

I am ab;e to make shopping cart however I am clueless how to store the shopping cart data into may database.
Can some body please help me with that
#83
Matthew Pennell
2931 days ago
charrik: To output the data for storing in a database, you could either use the contents of the cart session variable ($_SESSION[‘cart’]) and store that (obviously you would then need to break it up and look up the ids against your database when examining the data); or, you could adapt the showCart() function to store more verbose cart contents information in your database.
#84
Scott
2930 days ago
Hi Matthew,
Great tut, has helped me heaps! Im just now trying to send the variable $total to paypal for processing but it seams tied up in the showcart function and wont print anything to screen when I put echo $total…how do i release the variable from the function?
#85
Matthew Pennell
2930 days ago
Scott: Probably the easiest way would be to put it into a session variable at the point it is calculated in the showCart() function:

$_SESSION[‘total’] = $total;

Then you can echo the session variable in your PayPal form.
#86
Scott
2917 days ago
Thankyou Matthew :)
#87
Paul Drewett
2913 days ago
May I say what a fantastic article this was. I am trying to build my own php shopping cart and this was a perfect introduction/explanation.
I have learned lots about PHP as well and you have really really helped me – thank you.
This is a superb website design too. Fantastic user experience. Everything just where you would expect it. Wonderful work. I shall be adding a link from my site Monday morning.
Can’t wait to see whats on the rest of the watchmaker project.
Thank you again
Paul
#88
Prosadia Blue2
2903 days ago
Great Example
How Careful were you, the code is clear and easy to understand.
Another line, your site looks pretty, i love its style
#89
Jono
2892 days ago

This looks like a really cool tutorial, I’ll have to check it out again some time. It looks good for beginners and I’m a total beginner so thanks a lot.

I did notice one problem with the working example: After adding a bunch of products to the cart I clicked the back button a few times and it kept adding more products each time it went back to the view cart page.

Maybe that’s just me?

#90
Mike lawrence
2884 days ago

Fantastic tutorial i’m ready to have a go at – except for one thing – i cannot see how callbacks are handled – i understand they come back from, for example, Worldpay and then they have to be processed, to alter stock quanities etc. how are callbacks done and is there a tutorial?

Thanks

#91
Matthew Pennell
2884 days ago

Hi Mike – you would need a whole separate tutorial for that area, as it’s quite a big subject.

Most companies that do this sort of thing (e.g. PayPal, WorldPay, Protx, etc.) offer API documentation and example files/code to handle callbacks, so maybe check those out?

#92
Nick Tabram
2883 days ago

Fantastic tutorial sir. Helped me immensely. Thanks.

#93
Lya
2882 days ago

Hi,
Thanks for the tutorial. I have a problem, the session ($cart) is always false. When I add 1 product, it adds for first time, but when I go to cart.php it will shows that my shopping cart is empty. Any ideas?

Thanks

#94
Lya
2882 days ago

Hi,
Anyway is there anybody who ever try this shopping cart in opera and ie? I dunno but its only work in firefox in my comp >

#95
Matthew Pennell
2881 days ago

Lya: The demo works in all modern browsers. Make sure you have cookies enabled, as otherwise the session variables may not work properly.

#96
Lya
2881 days ago

I’ve enabled cookies and erase my prev cookies, but nothing work.

Can you help me to check
http://fleea.nl/Catwalk/user/index.php

If possible, use opera or ie. Thanks a lot

#97
Matthew Pennell
2881 days ago

Your site behaves exactly the same for me in Firefox, IE and Opera – it doesn’t work correctly in any of them.

Whatever you’ve done when you changed the target of the ‘add’ links to point to index.php instead of cart.php has screwed up the way the cart keeps track of its contents. You’ve also removed the table of items from the cart.php page.

I suggest you go back to the original code, then make your changes and see at what point it breaks.

#98
Lya
2881 days ago

Hi Matthew,
thanks a lot for fast response. I think I fix it already. I will test it in other computer tomorrow, but now in my comp, when I delete cookies and do somethings, its still going well, either in opera, ie and firefox.

Thanks for suggesting me come back to original code, I think I screw up session_start() and return from function.inc.php

This website is only for internal school, but I will make sure I provide some link to this web ^^

#99
Rajesh
2876 days ago

Hi !

Great Tutorial !!

How about we also add an admin login panel. Something which will allow the store owner to add, remove, edit product infos .. Can you help me with the code ?

#100
Rob
2871 days ago

Thanks for a great tutorial. I’m nearly there with it, but I want to be able to access the cart from various pages and directores on my site – more of a shortlist facilty than a ashopping basket. At the moment, the cart page is automatically loaded when a selection is made. Is there any way to stop that?

Thanks agian

#101
Matthew Pennell
2871 days ago

Rob: To stop the addition buttons automatically going to the cart page, you could just direct them to the current page – you would need to replicate the ‘adding items’ functionality on each page – or I guess you could do it with Ajax instead if you knew your Javascript.

#102
Rob
2870 days ago

Hi Matthew,
Thanks for getting back to me. Where and how do I change the redirection you mentioned. As you may have gathered I’m not exactly an expert at all this!

Thanks again,

Rob

#103
Matthew Pennell
2870 days ago

Rob: You need to change the <a href="cart.php"> links to instead point to the page they are on.

#104
Jonathan
2862 days ago

This is awesome! Only… is it also possible to check out; can you automatically mail the contents of the basket with shipping details?

#105
Matthew Pennell
2861 days ago

Jonathan: You’d have to build that functionality yourself!

#106
adrian
2861 days ago

great tutorial! having a problem with one error.. cart is always undefined
on the first addition to the basket..once the page is refreshed or another item is added to the cart the variable is defined..any ideas??

Notice: Undefined index: cart in c:\program files\easyphp1-8\www\cart.php on line 12

the same occurs when visiting the cart.php through a direct link without adding anything to the cart with the variable ‘action’

Notice: Undefined index: action in c:\program files\easyphp1-8\www\cart.php on line 13

any help would be great

#107
adrian
2857 days ago

i got round this by turning off php warnings as there is no aparent problem with the code

#108
tom
2847 days ago

I installed exatly, but when I add an item, then go back add another item again, the previous is lost. Can you explain. Thanks.

#109
Tyler Pederson
2845 days ago

I tried for a couple days to make the exploding strings method work with passing quantities from the getgo, but in the end I made the cart session variable an array.

switch ($action) {
case ‘add’:
if ($cart) {
if ($cart[$id]) {
$cart[$id] += $_POST[‘quantity’];
} else {
$cart[$id] = $_POST[‘quantity’];
}
} else {
$cart = array();
$cart[$id] = $_POST[‘quantity’];
}
break;
case ‘delete’:
if ($cart) {
unset($cart[$id]);
}
break;
case ‘update’:
if ($cart) {
foreach ($_POST as $key=>$value) {
if (stristr($key,’qty’)) {
$id = str_replace(‘qty’,’’,$key);
$cart[$id] = $value;
}
}
}
break;
}
$_SESSION[‘cart’] = $cart;

The functions were also changed.

function writeShoppingCart() {
$cart = $_SESSION[‘cart’];
if (!$cart) {
return ‘0 items’;
} else {
// Parse the cart session variable
$s = (count($items) > 1) ? ’s’:’’;
return ‘You have ’.count($cart).’ item’.$s.’ in your shopping cart’;
}
}

And showCart() was mostly the same except I changed:

# if ($cart) {

# $items = explode(’,’,$cart);

# $contents = array();

# foreach ($items as $item) {

# $contents[$item] = (isset($contents[$item])) ? $contents[$item] + 1 : 1;

# }

# $output[] = ‘’;

# $output[] = ‘’;

# foreach ($contents as $id=>$qty) {

into:

$cart = $_SESSION[‘cart’];
if ($cart) {
$output[] = ‘’;
$output[] = ‘’;
foreach ($cart as $id=>$qty) {

I hope this is helpfull to someone, I appologise if this is outside the original intent of the article.

#110
Carlos
2839 days ago

Your scrit & tutorial are excellent. I was looking for a VERY simple Shopping Cartt and yours is the simplest I have found..

I have found a problem. If I turn Cookies off, the script will only add one item at a time to the cart, deleting the one that was there before..

For my uses I would like to have something that works without cookies, if at all possible.

Thank you again for a great tutorial & script.

#111
Carlos
2831 days ago

I found the source of the problem, i.e. why turning off cookies the cart would not work. It has nothing to do with the script it was the settings in php.ini.

I had trouble locating the real php.ini to edit it. I’m using Mac OS X as my development server.

#112
Matthew Pennell
2822 days ago

I’m closing comments on this article due to the volume of comment spam it is attracting. If you really can’t find the answer you need elsewhere, my contact details are on the contact page of this site.

#113