PHP summing values from database - multidimensional arrays - php

I need to calculate a sub total of the items in a shopping cart. It stores the items added to the cart as an array of the product IDs in a session variable.
So to start with I need to use the ID in the cart array to pull the product information from the database (name, price etc.) and then add the prices of all the items in the cart, of which there could be more than one of the same product.
My test cart should have a total price of 96,049.98 but my code is returning a total price of 18. I don't know where it's getting that from.
Here is the code:
function subTotal() {
global $db;
global $table_prefix;
$table = $table_prefix . "products";
foreach($_SESSION['cart'] as $item) {
$sql = $db->prepare("SELECT * FROM $table WHERE id = :id");
$sql->bindParam(":id", $item[0]);
$sql->execute();
$amount = 0;
$product = $sql->fetch(PDO::FETCH_ASSOC);
foreach($product as $price) {
$amount += $price['price'];
}
}
return $amount;
}

You are restarting the value $amount to 0 per iteration.
Try initializating it at the top:
function subTotal() {
global $db;
global $table_prefix;
$table = $table_prefix . "products";
$amount = 0; //MOVED HERE at the top
foreach($_SESSION['cart'] as $item) {
$sql = $db->prepare("SELECT * FROM $table WHERE id = :id");
$sql->bindParam(":id", $item[0]);
$sql->execute();
$product = $sql->fetch(PDO::FETCH_ASSOC);
foreach($product as $price) {
$amount += $price['price'];
}
}
return $amount;
}

Just take out $amount = 0 out of the loop. As it's getting reset on each product loop.
$amount = 0;
foreach($_SESSION['cart'] as $item) {
$sql = $db->prepare("SELECT * FROM $table WHERE id = :id");
$sql->bindParam(":id", $item[0]);
$sql->execute();
$product = $sql->fetch(PDO::FETCH_ASSOC);
foreach($product as $price) {
$amount += $price['price'];
}
}

As I mentioned in my comment: In case you are able to change the way your shopping cart stores items, you could refactor your code to something like this:
function subTotal() {
$db = $GLOBALS['db'];
$table_prefix = $GLOBALS['table_prefix'];
$table = $table_prefix . "products";
$totalPrice = 0;
// assuming that you actually store ($id => $amount) pairs
$ids = join(',', array_map('intval', array_keys($_SESSION['cart'])));
$stmt = $db->prepare("SELECT id, price FROM $table WHERE id IN ($ids)");
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$amount = $_SESSION['cart'][$row['id']];
$totalPrice += $amount * $row['price'];
}
return $totalPrice;
}
If would assume, that your shopping cart variable would contain something like this:
array(
4 => 1, // 1 item with ID 4
22 => 8 // 8 items with ID 22
)

Related

Update row with more that one item?

Here is my products table
And here is my cart table
When the transaction is finished i would like to update my products table(sizes) only with $new_quantity
My code looks like:
$cartQ=$db->query("SELECT * FROM cart WHERE id='{$cart_id}'");
$result=mysqli_fetch_assoc($cartQ);
$items=json_decode($result['items'],true);
foreach ( $items as $item) {
$product_id = $item['id'];
$product_quantity=$item['quantity'];
$product_size=$item['size'];
$productQ = $db->query("SELECT * FROM products WHERE id='{$product_id}'");
$product = mysqli_fetch_assoc($productQ);
$productSizes=$product['sizes'];
$sArray = explode(',', $productSizes);
foreach ($sArray as $sizeString) {
$s = explode(':', $sizeString);
$size=$s[0];
$quantity=$s[1];
$threshold=$s[2];
}
}
$quantity_updateQ=$db->query("SELECT sizes FROM products WHERE id='{$product_id}'");
$quantity_update=mysqli_fetch_assoc($quantity_updateQ);
$new_quantity=intval($quantity-intval($product_quantity));
echo $new_quantity;
var_dump($product_id);
$quantity_finished=$db->query("UPDATE products SET sizes= '{$new_quantity}' WHERE id='{$product_id}'");

how to pass two arrays to view in codeigniter

Im not pro in programming
i have a foreach loop that gets the values from a form calculating the total and subtotal
public function salecal()
{
if ($this->input->post())
{
$i = 0;
$data = array();
$subtotal = 0;
foreach($this->input->post('pname') as $d){
$data[] = array(
'pid' => $this->input->post('pid[]')[$i],
'pname' => $this->input->post('pname[]')[$i],
'quantity' => $this->input->post('qty[]')[$i],
);
foreach ($data as $entry) {
$qty = $entry['quantity'];
$pid = $entry['pid'];
$proname = $entry ['pname'];
}
$value = $this->insert_model->get_price($pid); ///pasing the product id to get the the price from database
foreach ($value->result() as $row)
{
$price = $row->price;
}
$total = $price * $qty; ////Total calculation
$subtotal = $subtotal + $total;/////Sub Total Calculation
$i++;
}
$result = compact("proname", "price", "qty", "total","i", "subtotal");
$this->load->view("bill", $result);
}
}
when i run this code im getting only the finally entered products details but the subtotal is correct
but the data inserting form is dynamic
what i want as result is
user will insert several or one item with quantity
data should be calculated and pass the calculated values to view
but currently im getting it only for the last inserted data please help me how to catch all the datas that user insert to form and how to pass them to view
Because your overwriting the variables consequently so it's passing last overwrite value only . you should make array for each one
This how you need to send all data to view using array
<?php
public function salecal()
{
if ($this->input->post())
{
$i = 0;
$data = array();
$subtotal = 0;
$final_array_collection =array();
foreach($this->input->post('pname') as $d){
$total =0; //reset the total to zero for each product
$pid = $this->input->post('pid[]')[$i];
$pname = $this->input->post('pname[]')[$i];
$quantity = $this->input->post('qty[]')[$i];
$value = $this->insert_model->get_price($pid); ///pasing the product id to get the the price from database
foreach ($value->result() as $row)
{
$price = $row->price;
}
$total = $price * $quantity; ////Total calculation
$subtotal = $subtotal + $total;/////Sub Total Calculation
$final_array_collection[] =array("proname"=>$pname, "price"=>$price, "qty"=>$quantity, "total"=>$total,"i"=>$i, "subtotal"=> $subtotal);
$i++;
}
$result = compact("final_array_collection");
$this->load->view("bill", $result);
}
}
?>

Echo out one value from an array

I selected an array of product IDs and product names from the table product. I tried to echo out only one product name from the array, but all I got was the first letter of the product name. Below is my code. Thanks in advance for any tips.
$info1 = $conn->prepare("SELECT `productid`,`productname` FROM `$product` WHERE id = :id ORDER BY `productname` ASC ");
$info1 ->bindParam(':id', $sessionid , PDO::PARAM_INT);
$info1->execute();
while ($userinfo1 = $info1->fetchobject()) {
$productid = "$userinfo1->productid";
$productname = "$userinfo1->productname";
}
echo $productname[0];
Add brackets to the variables inside the while loop to create the array
while ($userinfo1 = $info1->fetchobject()) {
$productid[] = "$userinfo1->productid";
$productname[] = "$userinfo1->productname";
}
echo $productname[0];//this will print the first productname
I think is better make just 1 array of objects
$array=array();
while ($userinfo1 = $info1->fetchobject()) {
$array[] = $userinfo1;
}
echo $array[0]->productname;
instead of doing this :
$info1 = $conn->prepare("SELECT `productid`,`productname` FROM `$product` WHERE id = :id ORDER BY `productname` ASC ");
$info1 ->bindParam(':id', $sessionid , PDO::PARAM_INT);
$info1->execute();
while ($userinfo1 = $info1->fetchobject()) {
$productid = "$userinfo1->productid";
$productname = "$userinfo1->productname";
}
echo $productname[0];
Do this :
$info1 = $conn->prepare("SELECT `productid`,`productname` FROM `$product` WHERE id = :id ORDER BY `productname` ASC ");
$info1 ->bindParam(':id', $sessionid , PDO::PARAM_INT);
$info1->execute();
$counter =0;
while ($userinfo1 = $info1->fetchobject()) {
$productid[] = "$userinfo1->productid";
$productname[] = "$userinfo1->productname";
echo $productid[counter];
echo $productname[counter];
counter++;
}
this way you'll echo out every value of the array
You have various options at your disposal. Take your look for instance, you could create an associative array like the following:
$items = array();
while ($userinfo1 = $info1->fetchobject()) {
$item = array(
'productid' => $userinfo1->$productid,
'productname' => $userinfo1->$productname
);
array_push($items, $item);
// or you could use native
// $uitems[] = $item;
}
That would give you an array ($users) that you could loop through and fetch for set index:
foreach($items as $item) {
print_r($item); // prints the whole user item.
//print $item['productid']; /* or even print the users product id.*/
}
Or simple for one item like you requested:
echo $items[0]['productid'];
Alternatively: if you'd like seperate arrays, you could do as stated in the other answers:
while ($userinfo1 = $info1->fetchobject()) {
$productid[] = "$userinfo1->productid";
$productname[] = "$userinfo1->productname";
}

php emailing an array

I am trying to email the results held in an array ( shopping cart ) however when I send the email it is only the first name, price and qty which is displayed in the email and not any of the other names, prices or qty's. I am assuming there is something wrong with my loop but not sure where. Many thanks in advance. The results are placed in the comma_separated variable
$result= mysqli_query($conn, "SELECT * FROM testtable ");
// save product list as array
if (mysqli_num_rows($result) > 0) {
while($row = mysqli_fetch_object($result))
{
$sku = $row->ProductSKU;
$productInfo[$sku] = array();
$productInfo[$sku]['Name'] = $row->Name;
$productInfo[$sku]['Price'] = $row->Price;
$productInfo[$sku]['QTY'] = $row->QTY;
}
} else {
die ("ERROR");
}
$i=0;
$total=0;
// print the currently selected items
foreach ($_SESSION['cart'] as $sku => $quantity) {
$subtotal = $quantity * $productInfo[$sku]['Price'];
$total += $subtotal;
$array = array("Product:".$productInfo[$sku]['Name'],
"Units #".$productInfo[$sku]['Price'] ,
"Total:".number_format($subtotal, 2));
$comma_separated = implode("\n", $array);
}
You should probably change the following code:
// print the currently selected items
foreach ($_SESSION['cart'] as $sku => $quantity) {
$subtotal = $quantity * $productInfo[$sku]['Price'];
$total += $subtotal;
$array = array("Product:".$productInfo[$sku]['Name'],
"Units #".$productInfo[$sku]['Price'] ,
"Total:".number_format($subtotal, 2));
$comma_separated = implode("\n", $array);
}
into:
// print the currently selected items
$comma_separated = array();
foreach ($_SESSION['cart'] as $sku => $quantity) {
$subtotal = $quantity * $productInfo[$sku]['Price'];
$total += $subtotal;
$array = array("Product:".$productInfo[$sku]['Name'],
"Units #".$productInfo[$sku]['Price'] ,
"Total:".number_format($subtotal, 2));
$comma_separated[] = implode(', ',$array);
}
$comma_separated = implode("\n", $comma_separated);
Earlier you have created product array, imploded it using new line but finally you haven't saved this array in any other variable, so each time you run foreach loop you initialized $comma_separated variable again so the previous value wasn't there.
Now you should append $comma_separated to mail content, for example:
$mail_content .= $comma_separated;

Add another dimension into array cart

I have a shopping cart, which works just fine, but I would like to store type of goods (for example color, size, etc.).
Here is a function that gets items from shopping cart
public static function getCart() {
if((isset($_SESSION['cart'])) && count($_SESSION['cart'])>0) {
$ids = "";
foreach($_SESSION['cart'] as $id => $quantity) {
$ids = $ids . $id . ",";
}
$ids = rtrim($ids, ',');
$dotaz = dibi::fetchAll("SELECT * FROM eshop_products WHERE idProduct IN ({$ids})");
return $dotaz;
} else {
//do nothing
}
}
And function that adds items to shopping cart
public static function addToCart($data) {
$id = $data['id'];
$quantity = $data['qty'];
$varianta = $data['varianty']; //THIS IS WHAT I NEED TO ADD TO SESSION ARRAY
if(!isset($_SESSION['cart'])) {
$_SESSION['cart'] = array();
}
if(isset($_SESSION['cart'][$id])) {
$_SESSION['cart'][$id] += $quantity;
} else {
$_SESSION['cart'][$id] = $quantity;
}
}
Is there some easy way to do that? I googled some tutorials, but still no success.
Thank you.
Maybe this is a hint for you:
$id = $data['id'];
$quantity = $data['qty'];
$varianta = $data['varianty']; //THIS IS WHAT I NEED TO ADD TO SESSION ARRAY
$cart = array();
array_push($cart, array(
'id' => $id,
'quantity' => $quantity,
'varianta' => $varianta
));

Categories