<?php /** * Redis + 單例型購物車 * param $basket 存儲商品信息 * param $ins 存儲實例化對象 */ namespace lib; use redis\Redis; class Cart{ private $expire = 43200; //redis購物車商品緩存過期時間 private $redis = Null; private $redis_ext = ''; //redis緩存鍵名拼接字符串 private $cachekey = Null; private $basket = []; //私有空數組用於存放商品信息 /** * 購物車初始化,傳入用戶id */ public function init($user_id){ $this->redis = Redis::ins(); //調用redis緩存類(連接redis) $this->redis_ext = '.'.config('system')['project_name_zn']; //redis緩存鍵名拼接項目中文名稱字符串 $this->cachekey = "user.cart.{$user_id}".$this->redis_ext; //redis緩存鍵名拼接用戶ID與項目中文名稱字符串為對象用戶購物車緩存鍵名 $this->basket = json_decode($this->redis->get($this->cachekey),true); //獲取對象用戶的redis購物車商品緩存信息並解碼為PHP數組 } //添加商品 $id 商品ID $attr_id 商品對應屬性ID $goodsName 商品名稱 $number 加入數量 $price 商品對應屬性單價 public function addbasket( $id, $attr_id, $goodsName, $attr_name, $number, $price , $freight ){ //判斷對象商品是否已經存在redis購物車商品緩存內 if( $this->isExist($id,$attr_id) ){ //存在時增加該對象商品數量 return $this->add($id, $attr_id ,$number); } //對象商品不在redis購物車商品緩存內時 $tmp = []; $tmp['goods_id'] = intval($id); //對象商品ID $tmp['attr_id'] = intval($attr_id); //對象商品對應屬性ID $tmp['goods_name'] = $goodsName; //對象商品名稱 $tmp['attr_name'] = $attr_name; //對象商品名稱 $tmp['goods_number'] = intval($number); //對象商品數量,新增的商品默認加入數量為1 $tmp['price'] = intval($price); //對象商品對應屬性單價 $tmp['freight'] = intval($freight); //對象商品運費 $tmp['subtotal'] = $tmp['goods_number'] * $price; //對象商品總價 $this->basket[] = $tmp; //新的商品信息存入redis購物車商品緩存信息解碼的PHP數組內,每件屬性商品信息對應一個索引鍵值 //重新將新的購物車商品信息數組編碼為json字符串存入對象用戶redis購物車商品緩存內 $this->redis->setex($this->cachekey,$this->expire,json_encode($this->basket)); return 1; } //判斷商品是否已經存在 // $id 商品ID // $attr_id 商品屬性ID public function isExist($id,$attr_id){ $isExist = false; //當對象用戶redis購物車商品緩存不為空時 if( !empty($this->basket) ){ foreach ($this->basket as $key=>$val){ if( $val['goods_id'] == $id && $attr_id == $val['attr_id'] ){ $isExist = true; break; } } } return $isExist; } //獲取所有商品信息 public function getAll(){ return $this->basket; } //獲取部分商品信息 public function getPartGoods($ids) { $goods = []; foreach ($ids as $v) { foreach ($this->basket as $k => $val) { if ($val['goods_id'] == $v['goods_id'] && $val['attr_id'] == $v['attr_id']) { $goods[] = $val; } } } return $goods; } //獲取部分商品總數 public function getPartGoodsNum($ids) { $number = ''; foreach ($ids as $v) { foreach ($this->basket as $k => $val) { if ($val['goods_id'] == $v['goods_id'] && $val['attr_id'] == $v['attr_id']) { $number += $val['goods_number']; } } } return $number; } /*添加商品 * @param $id商品id * @param $number 添加的數量 默認為1 * @param $type 1為在原有商品數上添加 總商品數= 當前數 + 歷史數,2為總商品數 默認為 1 */ public function add($id, $attr_id ,$number){ $goods_number = 0; //加入不成功時默認返回添加數量為0 //商品ID不為空並且商品在redis購物車商品緩存內 if( !empty($id) && $this->isExist($id ,$attr_id) ){ $cache_detail = $this->basket; //獲取用戶購物車所有商品信息 foreach ($cache_detail as $key=>$val){ if( $val['goods_id'] == $id && $val['attr_id'] == $attr_id){ $val['goods_number'] = $val['goods_number']+$number; //購物車存在該商品時增加該商品數量 $val['subtotal'] = $val['goods_number']*$val['price']; //購物車存在該商品時重新計算該件商品總價 $this->basket[$key] = $val; //購物車存在該商品時重新將新的商品信息放入該商品的redis緩存信息內($key即為該商品的redis緩存鍵值) $this->redis->setex($this->cachekey,$this->expire,json_encode($this->basket)); //購物車存在該商品時更新該商品的redis緩存信息 $goods_number = $val['goods_number']; //商品加入成功將商品數量賦值變量返回 break; } } } return $goods_number; //返回商品數量 } //減一商品 public function reduce($id, $attr_id ,$number){ $goods_number = 0; if(!empty($id) && $this->isExist($id ,$attr_id )){ $cache_detail = $this->basket; foreach ($cache_detail as $key=>$val){ if( $val['goods_id'] == $id && $val['attr_id'] == $attr_id ){ $val['goods_number'] = $val['goods_number']-$number; $goods_number = $val['goods_number']; //若為0則刪除 if( $val['goods_number'] <= 0 ){ $this->dele($id ,$attr_id); $this->redis->setex($this->cachekey,$this->expire,json_encode($this->basket)); $goods_number = 0; break; } $val['subtotal'] = $val['goods_number']*$val['price']; $this->basket[$key] = $val; $this->redis->setex($this->cachekey,$this->expire,json_encode($this->basket)); break; } } } return $goods_number; } //刪除商品 public function dele($ids){ if(is_array($ids)){ foreach ($ids as $v){ foreach ($this->basket as $k=>$val) { if( $val['goods_id'] == $v['goods_id'] && $val['attr_id'] == $v['attr_id'] ){ array_splice($this->basket,$k,1); } } } }else{ foreach ($this->basket as $k=>$val) { if( $val['goods_id'] == $ids){ //unset(self::$basket[$k]); array_splice($this->basket,$k,1); } } } $this->redis->setex($this->cachekey,$this->expire,json_encode($this->basket)); return true; } //清空購物車 public function emptyCart(){ return $this->redis->del($this->cachekey); } //部分商品總價(包含商品運費) $type不為0時商品總價與商品總運費作為關聯數組返回 public function getTotalPrices($ids,$type=0) { $totalPrice = 0; $goods_freight = []; $freight = 0; foreach ($ids as $v) { foreach ($this->basket as $k => $val) { if ($val['goods_id'] == $v['goods_id'] && $val['attr_id'] == $v['attr_id']) { $totalPrice += $val['subtotal']; $goods_freight[$v['goods_id']] = $val['freight']; //獲取不同商品的運費 } } } //相同商品不同屬性只收取一次運費 foreach ( $goods_freight as $value ){ $freight += $value; } if ($type == 0){ return $totalPrice+$freight; //總價=商品總價+商品總運費 }else{ return ['total_price'=>$totalPrice,'freight'=>$freight]; //商品總價與商品總運費 } } //編輯某商品數量 public function edit($id, $attr_id, $number) { if (!empty($id) && $this->isExist($id, $attr_id) && $number > 0) { $cache_detail = $this->basket; foreach ($cache_detail as $key => $val) { if ($val['goods_id'] == $id && $val['attr_id'] == $attr_id) { $val['goods_number'] = intval($number); $val['subtotal'] = $val['goods_number'] * $val['price']; $this->basket[$key] = $val; return $this->redis->setex($this->cachekey, $this->expire, json_encode($this->basket)); } } } } }