【问题标题】:Updating db for items in shopping cart is adding both items into one line为购物车中的项目更新数据库是将两个项目添加到一行中
【发布时间】:2018-09-18 15:34:52
【问题描述】:

当我处理包含两件商品的购物车时。数据库用新的可用数量更新每个项目的大小,但如果购物车中有多个项目,那么第二/第三/第四个项目的大小会随着新的可用数量更新很好,但第一个项目会选择其他项目数量并将它们添加到尺寸详细信息并更新项目自己的尺寸详细信息。

我在订单确认页面中调整库存详情

//调整库存

  $itemQ = $db->query("SELECT * FROM cart WHERE id = '{$cart_id}'");
  $iresults = mysqli_fetch_assoc($itemQ);
  $items = json_decode($iresults['items'],true);

foreach($items as $item){
 $newsizes = array();
 $item_id = $item['id'];
 $productQ = $db->query("SELECT sizes FROM products WHERE id = '{$item_id}'");
 $product = mysqli_fetch_assoc($productQ);
 $sizes = sizesToArray($product['sizes']);

 foreach($sizes as $size){
   if($size['size'] == $item['size']){
   $q = $size['quantity'] - $item['quantity'];
   $newSizes[] = array('size' => $size['size'],'quantity' => $q);
  }else{
  $newSizes[] = array('size' => $size['size'],'quantity' => $size['quantity']);
 }
}
 $sizesString = sizesToString($newSizes);
 $db->query("UPDATE products SET sizes = '{$sizesString}' WHERE id = '{$item_id}'");
}

我的函数 sizeToString 和 sizesToArray 存储在帮助文件中

function sizesToArray($string){
$sizesArray = explode(',',$string);
$returnArray = array();
foreach($sizesArray as $size){
  $s = explode(':',$size);
  $returnArray[] = array('size' => $s[0], 'quantity' => $s[1]);
}
return $returnArray;
}

function sizesToString($sizes){
$sizesString = '';
foreach($sizes as $size){
  $sizesString .= $size['size'].':'.$size['quantity'].',';
}
$trimmed = rtrim($sizesString, ',');
return $trimmed;
}

我浏览了我的代码,但我看不出它正在做的事情的原因。 我的想法是,如果我的代码是循环的,那么在数据库中更新的每个项目都会有同样的问题,而不仅仅是第一个项目。

任何帮助将不胜感激。

编辑 Helpers.php

function sizesToArray($string){
$sizesArray = explode(',',$string);
$returnArray = array();
foreach($sizesArray as $size){
  $s = explode(':',$size);
  $returnArray[] = array('size' => $s[0], 'quantity' => $s[1]);
}
return $returnArray;
}

function sizesToString($sizes){
$sizesString = '';
foreach($sizes as $size){
  $sizesString .= $size['size'].':'.$size['quantity'].',';
}
$trimmed = rtrim($sizesString, ',');
return $trimmed;
}

1) - 购物车的内容 在 db 表购物车中,项目字符串是这样保存的

  [{"id":"247","size":"W5000W","quantity":2}]
  [{"id":"242","size":"MK120","quantity":"2"}]

2) - 产品内容 在购物车结帐之前,尺寸字符串看起来像这样

 Prod id: 247
 sizes: W5000W:20 
 Prod id: 242
 sizes: MK120:20

3) 结帐后的预期结果:

  Prod id: 247
  sizes: W5000W:18 
  Prod id: 242
  sizes: MK120:18

4) 结帐后的实际结果: 购物车结帐后,尺寸字符串看起来像这样(在我订购了每件商品两个之后)

Prod id: 247
sizes: W5000W:18, MK120:18
Prod id: 242
sizes: MK120:18

注意:prod id 247 首先添加到购物车,

编辑 18/9

我有一个显示我的可用数量的选择框

  <select name="size" id="size" class="form-control">
         <option value=""></option>
         <?php foreach($size_array as $string) {
         $string_array = explode(':', $string);
         $size = $string_array['0'];
         $available = $string_array['1'];
        if ($available > 0){
            echo '<option value="'.$size.'" data-available="'.$available.'">'.$size.' 
            ('.$available.' Available)</option>';
        }
        if ($available <= 0){
          echo '<option value="">No more left</option>';
        }
      } ?>
     </select><br>

这在我的产品页面底部:

 jQuery('#size').change(function(){
  var available = jQuery('#size option:selected').data("available");
  jQuery('#available').val(available);
 });

我的页脚中有这个,这是库存数量的验证。理论上我正在写的东西有效,但不想在现实中工作。

function add_to_cart(){
  jQuery('#product_errors').html("");
  var size = jQuery('#size').val();
  var quantity = jQuery('#quantity').val();
  var available = parseInt(jQuery('#available').val());
  var error = '';
  var data = jQuery('#add_product_form').serialize();

  if (size == '' || quantity == '' || quantity == 0){
    error += '<div class="alert alert-danger alert-dismissible" i 
    id="product_errors"><a href="#" class="close" data-dismiss="alert" aria- 
    label="close">&times;</a><strong>Error!</strong> You must select a size 
      and quantity before continuing.</div>';
   jQuery('#product_errors').html(error);
   return;
   } else if (quantity > available){
     error += '<div class="alert alert-danger alert-dismissible" 
   id="product_errors"><a href="#" class="close" data-dismiss="alert" aria- 
   label="close">&times;</a><strong>Error!</strong> We have only 
   '+available+' available. </div>';
    jQuery('#product_errors').html(error);
    return;
  } else{
   $.ajax({
  url : 'add_cart.php',
  method : 'post',
  data : data,
  success : function(){
    location.reload();
    window.location.href = "basket.php";
  },
  error : function(){alert("Something went wrong");},
  });
  }
  }

【问题讨论】:

  • 您可能希望在一条 SQL 语句中执行此操作 - 类似于 UPDATE products, cart SET products.sizes = products.sizes - cart.sizes WHERE cart.cart_id = 17 AND cart.product_id = products.id
  • 我不想将购物车中的尺寸更新为名为 items 的项目字符串。我只想用新的尺寸值更新我的产品表、尺寸字段,而不是将第二个项目添加到添加到购物车的第一个项目中..
  • 如果您的库存表有 PRODUCT_ID、PRODUCT_SIZE、PRODUCT_QUANTITY 列,您可以简单地遍历购物车中的项目,并为每个项目更新相应产品和尺寸的库存与新数量.
  • 在我的产品表中,我有一个名为:sizes 的字段,其中存储了如下信息:ABCDE:20 - 这是产品型号:可用数量。我认为这里的问题是调整库存时的这段代码 $sizesString = sizesToString($newSizes); $db->query("UPDATE products SET sizes = '{$sizesString}' WHERE id = '{$item_id}'");我不认为它来自产品 1;更新可用数量,然后只有产品 2.. 等等..
  • 补充一下,您在第一次回复中提到了购物车表,我的购物车存储的产品如下:[{"id":"1","size":"VSK3000B","quantity" :"1"}]

标签: php


【解决方案1】:

您在单个单元格中保存多个值的方法是错误的 - 您的表格实际上应该是这样的:

+------------+---------+----------+
| Product_id | Size_id | Quantity |
+------------+---------+----------+
|     247    |    7    |     20   |
+------------+---------+----------+
|     242    |    4    |     20   |
+------------+---------+----------+

此外,您还需要 2 个其他表格 - 产品和尺寸:

+------------+--------------+
| product_id | product_name |
+------------+--------------+
|     247    | Jacket       |
+------------+--------------+
|     242    | Shoe         |
+------------+--------------+

+---------+-----------+
| size_id | size_name |
+---------+-----------+
|   7     | W5000W    |
+---------+-----------+
|   4     | MK120     |
+---------+-----------+

无论如何,如果你想继续使用你的数据模型,那么代码应该是这样的:

function sizesToArray($string)
{
  $sizesArray = explode(',',$string);
  $returnArray = array();
  foreach($sizesArray as $size)
  {
    $s = explode(':',$size);
    // by using keyed array you are saving the FOREACH-loop 
    // for finding the relevant size
    $returnArray[$s[0]] = $s[1];
  }
  return $returnArray;
}

// you can also use array_map() to return an array of "SIZE:QUANTITY" elements
// and then use implode(",") on it
function sizesToString($sizes)
{
  $sizesString = '';
  // $sizes is keyed by SIZE_NAME
  foreach($sizes as $size_name => $size_qty)
  {
    $sizesString .= $size_name.':'.$size_qty.',';
  }
  $trimmed = rtrim($sizesString, ',');
  return $trimmed;
}

$itemQ = $db->query("SELECT * FROM cart WHERE id = '{$cart_id}'");
$iresults = mysqli_fetch_assoc($itemQ);
$items = json_decode($iresults['items'],true);

foreach($items as $item)
{
  $item_id = $item['id'];
  $productQ = $db->query("SELECT sizes FROM products WHERE id = '{$item_id}'");
  $product = mysqli_fetch_assoc($productQ);
  $sizes = sizesToArray($product['sizes']);
  $sizes[$item['size']] -= $item['quantity']; // we deduce the relevant q-ty
  $sizesString = sizesToString($sizes);
  $db->query("UPDATE products SET sizes = '{$sizesString}' WHERE id = '{$item_id}'");
}

【讨论】:

  • 谢谢 Ivo,我会尝试这些建议,看看我的进展如何。
  • Ivo,它起作用了,我的数量现在使用原始字符串更新。我确实有一个问题,我检查可用的库存水平,所以如果有人去订购比可用的东西它不会让他们。在我将代码更改为您的建议之前,它给了我正确的错误消息,现在它只是将值添加到购物车而不检查。我有这个代码:
  • 我已经编辑了我的原始帖子以包含新信息。验证背后的理论是正确的,应该可以工作,但我有一种感觉,因为我将数组更改为关于验证的建议没有识别要检查“可用”的内容..
  • 如果没有给定尺寸的库存 - 您的 option 标签丢失 data-available="0"。此外,仅当下拉列表中当前选择的选项发生更改时,您才更新 #available 的值 - 因此,如果使用未更改默认选择的内容,则您有一个空的 #available
  • Ivo,我留下了这样的选项框: if ($available > 0){ echo ''; } if ($available No more left';但我在声明表单时错过了隐藏的输入。因此,我添加了这一行,它有效:感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 2019-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-23
相关资源
最近更新 更多