CodeIgniter购物车数量不更新:同选项商品重复添加时被替换
购物车重复添加同品时替换而非累加数量的问题排查与解决
问题说明:当多次添加带有完全相同选项的商品至购物车时,系统会替换原有商品,而非累加其数量。
相关代码展示
购物车视图代码
<table class="table table-bordered table-hover"> <thead><!-- Table head --> <tr> <th class="active">Sl</th> <th class="active col-sm-4">Product</th> <th class="active col-sm-2">Real Price</th> <th class="active">Qty</th> <th class="active">Disc Price</th> <th class="active">Total</th> <th class="active">Action</th> </tr> </thead><!-- / Table head --> <tbody><!-- / Table body --> <?php $cart = $this->cart->contents() ; ?> <?php $counter =1 ; ?> <?php if (!empty($cart)): foreach ($cart as $item) : ?> <tr class="custom-tr"> <td class="vertical-td"> <?php echo $counter ?> </td> <td class="vertical-td"><?php echo $item['name'] ?></td> <td class="vertical-td"><?php echo $item['pkprice'] ?></td> <td class="vertical-td"> <input type="text" name="qty" style="width: 50px" value="<?php echo $item['qty'] ?>" onblur ="order(this);" id="<?php echo 'qty'.$item['rowid'] ?>" class="form-control"> </td> <td> <div class="input-group"> <span class="input-group-addon"> <input type="checkbox" id="<?php echo 'opt'.$item['rowid'] ?>" onclick="return price_checkbox(this)" name="custom_price" <?php echo $item['price_option'] == 'custom_price' ? 'checked':'' ?> data-placement="top" data-toggle="tooltip" data-original-title="Custom Price"> </span> <input type="text" name="price" value="<?php echo $item['price'] ?>" onblur ="order(this);" id="<?php echo 'pri'.$item['rowid'] ?>" class="form-control" <?php echo $item['price_option'] == 'custom_price' ? '':'disabled' ?> > </div> <input type="hidden" name="product_code" value="<?php echo $item['id'] ?>" id="<?php echo 'code'.$item['rowid'] ?>"> </td> <td class="vertical-td"><?php echo number_format($item['subtotal'], 2, '.', ',') ?></td> <td class="vertical-td"> <?php echo btn_delete('admin/order/delete_cart_item/' . $item['rowid']); ?> </td> </tr> <?php $counter++; endforeach; ?><!--get all sub category if not this empty--> <?php else : ?> <!--get error message if this empty--> <td colspan="6"> <strong>There is no record for display</strong> </td><!--/ get error message if this empty--> <?php endif; ?> </tbody><!-- / Table body --> </table>
控制器代码
public function add_cart_item_by_barcode(){ $product_code = $this->input->post('barcode', true); $result = $this->order_model->validate_add_cart_item($product_code); if($result){ $price = $this->check_product_rate($result->product_id, $qty=1); //product tax check $tax = $this->product_tax_calculate($result->tax_id, $qty=1, $price); $data = array( 'id' => $result->product_code, 'qty' => 1, 'price' => $price, 'buying_price' => $result->buying_price, 'name' => $result->product_name, 'pkprice' => $result->p_price, 'tax' => $tax, 'price_option' => 'general' ); $this->cart->update($data); $this->session->set_flashdata('cart_msg', 'add'); } redirect('admin/order/new_order/'.$flag ='add'); } public function check_product_rate($product_id=null, $qty=null) { //tier Price check $tire_price = $this->order_model->get_tire_price($product_id, $qty); if($tire_price) { return $price = $tire_price->tier_price ; } //special offer check $this->tbl_special_offer('special_offer_id'); $offer_price = $this->global_model->get_by(array("product_id"=>$product_id), true); if(!empty($offer_price)) { $today = strtotime(date('Y-m-d')); $start_date = strtotime($offer_price->start_date); $end_date = strtotime($offer_price->end_date); if (($today >= $start_date) && ($today <= $end_date)) { return $price = $offer_price->offer_price; } } //return regular rate $this->tbl_product_price('product_price_id'); $general_price = $this->global_model->get_by(array("product_id"=>$product_id), true); return $product_price = $general_price->selling_price; } /*** Product tax calculation ***/ public function product_tax_calculate($tax_id, $qty ,$price) { $this->tbl_tax('tax_id'); $tax = $this->global_model->get_by(array('tax_id'=>$tax_id), true); //1 = tax in % //2 = Fixed tax Rate if($tax){ if($tax->tax_type == 1) { $subtotal = $price * $qty; $product_tax = $tax->tax_rate * ($subtotal / 100); //return $result = round($product_tax, 2); return $result = $product_tax; }else { //$product_tax = $tax->tax_rate * $qty; $product_tax = $tax->tax_ra
问题根源分析
我一眼就看到了问题所在——你在控制器的add_cart_item_by_barcode方法里用错了购物车操作方法!
CodeIgniter的Cart类中,update()是用来修改已存在的购物车条目(比如调整数量、修改价格),它需要传入购物车条目的rowid来精准定位。如果你只传id而没有rowid,它会直接匹配第一个id相同的条目,把原有数据替换成你传入的新值,自然不会累加数量。
而正确的添加商品操作应该用$this->cart->insert($data),这个方法会自动检查购物车里是否存在相同的商品(通过id和可选的options判断唯一性),如果存在就自动累加数量,不存在则新增条目。
解决方案
只需要把控制器里的这一行:
$this->cart->update($data);
改成:
$this->cart->insert($data);
补充说明
如果之后你的商品需要支持不同属性(比如颜色、尺寸),记得在$data数组里加上options键,示例如下:
$data = array( // 其他原有属性... 'options' => array('color' => 'red', 'size' => 'M') );
这样Cart类会把id+options作为唯一标识,只有完全相同的商品+属性才会累加数量,不同属性的同品会作为单独条目存在。
内容的提问来源于stack exchange,提问作者Shoaib Mehmood
相关产品推荐
相关产品推荐

