ThinkPHP5+Redis單例型購物車


<?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));
                }
            }
        }
    }

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM