Cart duplicates item when add to them

Hi Team

I need some suggestions on my logic, meaning if i add item to the cart it adds but not as 1 instead on the cart 2 items. This is wrong, the first step i check was on the quantity column before it was 1 from the table on the database. Still this did not solve my problem, then i try to put some var qty = 1; but this also did not solve the problem. What could be the reason for this? How can i solve this?

// html code

<!-- Displaying Products Start -->
  <div class="container">
    <div id="message"></div>
    <div class="row mt-2 pb-3">
		<?php
    include 'dbconn.php';
    $stmt = $conn->prepare('SELECT * FROM products');
    $stmt->execute();
    $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
    foreach ($rows as $row):
        // Access the data using $row['column_name']
        $productID = $row['id'];
        $productName = $row['product_name'];
        // ...
?>
      <div class="col-sm-6 col-md-4 col-lg-3 mb-2">
        <div class="card-deck">
          <div class="card p-2 border-secondary mb-2">
            <img src="<?= $row['product_image'] ?>" class="card-img-top" height="250">
            <div class="card-body p-1">
              <h4 class="card-title text-center text-info"><?= $row['product_name'] ?></h4>
              <h5 class="card-text text-center text-danger"><i class="fas fa-zar-sign"></i>&nbsp;&nbsp;<?= number_format($row['product_price'],2) ?>/-</h5>

            </div>
            <div class="card-footer p-1">
              <form action="" class="form-submit">
                <div class="row p-2">
                  <div class="col-md-6 py-1 pl-4">
                    <b>Quantity : </b>
                  </div>
                  <div class="col-md-6">
                    <input type="number" class="form-control pqty" value="<?= $row['product_qty'] ?>">
                  </div>
                </div>
                <input type="hidden" class="pid" value="<?= $row['id'] ?>">
                <input type="hidden" class="pname" value="<?= $row['product_name'] ?>">
                <input type="hidden" class="pprice" value="<?= $row['product_price'] ?>">
                <input type="hidden" class="pimage" value="<?= $row['product_image'] ?>">
                <input type="hidden" class="pcode" value="<?= $row['product_code'] ?>">
                <button class="btn btn-info btn-block addItemBtn"><i class="fas fa-cart-plus"></i>&nbsp;&nbsp;Add to
                  cart</button>
              </form>
            </div>
          </div>
        </div>
      </div>
      <?php endforeach; ?>
    </div>
  </div>
  <!-- Displaying Products End -->

// jquery code

$(document).ready(function() {

    // Send product details in the server
    $(".addItemBtn").click(function(e) {
      e.preventDefault();
      var $form = $(this).closest(".form-submit");
      var pid = $form.find(".pid").val();
      var pname = $form.find(".pname").val();
      var pprice = $form.find(".pprice").val();
      var pimage = $form.find(".pimage").val();
      var pcode = $form.find(".pcode").val();

      var pqty = $form.find(".pqty").val();
	  var pqty = 1;

      $.ajax({
        url: 'action.php',
        method: 'post',
        data: {
          pid: pid,
          pname: pname,
          pprice: pprice,
          pqty: pqty,
          pimage: pimage,
          pcode: pcode
        },
        success: function(response) {
          $("#message").html(response);
          window.scrollTo(0, 0);
          load_cart_item_number();
        }
      });
    });

Before you continue, please tell me the price submitted from the form isn’t actually the price used to bill the customer is it?

If so, it would be very easy for anyoe who knows a bit about browsers to get stuff way cheaper than you actually sell it by editing the hidden field.

1 Like

e.g 12000 zar item for a phone, if i add this it double this price from the cart

Sorry, I’m not sure what you’re saying. Could you elaborate please?

@rpkamp , let me explain it by means of sharing before and after with screen shots. for you to see the problem.

// before
before

// after

// server side code

<?php
	session_start();
	require 'dbconn.php';

	// Add products into the cart table
	if (isset($_POST['pid'])) {
	  $pid = $_POST['pid'];
	  $pname = $_POST['pname'];
	  $pprice = $_POST['pprice'];
	  $pimage = $_POST['pimage'];
	  $pcode = $_POST['pcode'];
	  $pqty = $_POST['pqty'];
	  $total_price = $pprice * $pqty;

		$stmt = $conn->prepare('SELECT product_code FROM cart WHERE product_code=:pcode');
		$stmt->bindParam(':pcode', $pcode);
		$stmt->execute();
		$res = $stmt->fetch(PDO::FETCH_ASSOC);
		$code = $res['product_code'] ?? '';


	  if (!$code) {
	    $query = $conn->prepare('INSERT INTO cart (product_name, product_price, product_image, qty, total_price, product_code) VALUES (:pname, :pprice, :pimage, :pqty, :total_price, :pcode)');
		$query->execute([
		'pname' => $pname,
		'pprice' => $pprice,
		'pimage' => $pimage,
		'pqty' => $pqty,
		'total_price' => $total_price,
		'pcode' => $pcode
		]);
	    $query->execute();

	    echo '<div class="alert alert-success alert-dismissible mt-2">
						  <button type="button" class="close" data-dismiss="alert">×</button>
						  Item added to your cart!
						</div>';
	  } else {
	    echo '<div class="alert alert-danger alert-dismissible mt-2">
						  <button type="button" class="close" data-dismiss="alert">×</button>
						  Item already added to your cart!
						</div>';
	  }
	}

	// Get no.of items available in the cart table
	if (isset($_GET['cartItem']) && isset($_GET['cartItem']) == 'cart_item') {
		 $stmt = $conn->prepare('SELECT COUNT(*) as count FROM cart');
		$stmt->execute();
		$result = $stmt->fetch(PDO::FETCH_ASSOC);
		$rows = $result['count'];

    echo $rows;
	}

	// Remove single items from cart
	if (isset($_GET['remove'])) {
	  $id = $_GET['remove'];

		$stmt = $conn->prepare('DELETE FROM cart WHERE id = :id');
		$stmt->execute(['id' => $id]);

	if ($stmt->rowCount() > 0) {
    $_SESSION['showAlert'] = 'block';
    $_SESSION['message'] = 'Item removed from the cart!';
    header('location: cart.php');	
	} else {
    echo 'No item found in the cart with the specified ID.';
	}

	  $stmt->execute();

	  $_SESSION['showAlert'] = 'block';
	  $_SESSION['message'] = 'Item removed from the cart!';
	  header('location:cart.php');
	}

	// Remove all items at once from cart
	if (isset($_GET['clear'])) {
	  $stmt = $conn->prepare('DELETE FROM cart');
	  $stmt->execute();
	  $_SESSION['showAlert'] = 'block';
	  $_SESSION['message'] = 'All Item removed from the cart!';
	  header('location:cart.php');
	}

	// Set total price of the product in the cart table
	if (isset($_POST['qty'])) {
	  $qty = $_POST['qty'];
	  $pid = $_POST['pid'];
	  $pprice = $_POST['pprice'];

	  $tprice = $qty * $pprice;

	  $stmt = $conn->prepare('UPDATE cart SET qty=?, total_price=? WHERE id=?');
	  $stmt->bind_param('isi',$qty,$tprice,$pid);
	  $stmt->execute();
	}

	// Checkout and save customer info in the orders table
	if (isset($_POST['action']) && isset($_POST['action']) == 'order') {
		$name = $_POST['name'];
		$email = $_POST['email'];
		$phone = $_POST['phone'];
		$address = $_POST['address'];
		$pmode = $_POST['pmode'];
		$products = $_POST['products'];
		$grand_total = $_POST['grand_total'];

		$sql = "INSERT INTO orders (name, email, phone, address, payment_method, products, grand_total) VALUES (:fullname, :email, :phone, :address, :payment_method, :products, :grand_total)";
		$stmt = $conn->prepare($sql);

	$stmt->bindValue(':fullname', $name);
	$stmt->bindValue(':email', $email);
	$stmt->bindValue(':phone', $phone);
	$stmt->bindValue(':address', $address);
	$stmt->bindValue(':payment_method', $pmode);
	$stmt->bindValue(':products', $products);
	$stmt->bindValue(':grand_total', $grand_total);

	$stmt->execute();
	
	echo "Checkout information has been stored.";
	  $stmt->execute();
	  $stmt2 = $conn->prepare('DELETE FROM cart');
	  $stmt2->execute();
	  $data .= '<div class="text-center">
								<h1 class="display-4 mt-2 text-danger">Thank You!</h1>
								<h2 class="text-success">Your Order Placed Successfully!</h2>
								<h4 class="bg-danger text-light rounded p-2">Items Purchased : ' . $products . '</h4>
								<h4>Your Name : ' . $name . '</h4>
								<h4>Your E-mail : ' . $email . '</h4>
								<h4>Your Phone : ' . $phone . '</h4>
								<h4>Total Amount Paid : ' . number_format($grand_total,2) . '</h4>
								<h4>Payment Mode : ' . $pmode . '</h4>
						  </div>';
	  echo $data;
	}
?>

You have worse problems than the count being off:

  • the price is decided based on a value from the client, as I said this allows people to temper with the price, but even worse
  • your entire website has one cart. Not one cart per visitor, but one cart that is shared by all visitors.

If I were you I’d address these mayor issues first before you fret about details…

6 Likes

What is this supposed to do?

1 Like

Other more fundamental issues aside, you’re calling execute() twice here. Not sure if this is actually defined behaviour, but it appears that calling execute($params) is binding those parameters under the hood; and thus calling execute() again without argument will execute the exact previous statement. So you end up inserting the same item twice to the global cart.

2 Likes

Ah, true as well. :)

1 Like