zoukankan      html  css  js  c++  java
  • ThinkPHP5+Redis单例型购物车

    <?php
    /**
     * Redis + 单例型购物车
     * param $basket 存储商品信息
     * param $ins 存储实例化对象
     */
    namespace lib;
    
    use redisRedis;
    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));
                    }
                }
            }
        }
    
    }
  • 相关阅读:
    简单例子windows 共享内存 Demo -----(一)
    Qt qss浅析
    基于EntityFramework的权限的配置和验证
    快速获取Windows系统上的国家和地区信息
    Scorm 1.2 开发文档
    SQL Server 联表字段合并查询
    解决 ko mapping 数组无法添加新对象的问题
    SQL Server 数据库初始化准备脚本
    妾心如水,良人不来
    有趣的格子效果
  • 原文地址:https://www.cnblogs.com/shengxihui/p/10706336.html
Copyright © 2011-2022 走看看