<?php
/**
 * 购物车类分析
 * 1.无论在网站刷新了多少次页面,或者新增加了多少个商品。打开购物车查看,看到的结果都市一样的
 *         即,打开A商品刷新,打开B商品刷新,看到的购物车应该是一样的
 *         整站范围内购物车是全局有效有的。
 *     解决:将购物车的信息放在数据库,也可以放在session里。
 * 2.购物车全局有效,即购物车的实例只能有一个
 *         不能出现3个页面,,买3个商品,就形成了3个购物车实例
 *     解决:单例模式
 * 
 * 技术支持:seesion+single
 * 
 * 功能分析:
 * 判断某个商品是否存在
 * 添加商品
 * 删除商品
 * 修改商品的数量
 * 
 * 某商品数量+1
 * 某商品数量-1
 * 
 * 查询购物车的商品种类
 * 查询购物车的商品数量 
 * 查询购物车的商品总金额
 * 返回购物车里的所有商品
 * 清空购物车
 */
error_reporting('E^ALL');
session_start();//使用session必须开启session

class CartTool{
    //此处要要到单例模式
    private static $ins = null;
    private $items = array();//用空数组存储商品

    //为防止他人重写,此时使用final构造方法受保护,
    final protected function __construct(){

    }
    //防止被克隆,
    final protected function __clone(){}

    //获取实例。开发一个方法供外部调用
    protected static function getIns(){
        //判断$ins是否是自身的实例
        // if(!(self::$ins instanceof self)){
        if(self::$ins === null){//若属性为null则是第一次访问
            self::$ins = new self();
        }
        return self::$ins;
    }
    
    //将购物车的单例对象放到session里面
    public static function getCart(){//只需此处让外部实例化购物车,其他全部受保护啊
        //sessoin里面没有购物车,或者不是session里面的实例
        if(!isset($_SESSION['cart']) || !($_SESSION['cart'] instanceof self)){
            $_SESSION['cart'] = self::getIns();
        }
        return $_SESSION['cart'];
    }
    /**
     * 添加商品,必须有商品id,名称,价格,数量
     * @parm int $goods_id商品主键
     * 因为主键不可能重复,此时用$goods_id作为数组的索引,下标
     */
    public function addItem($goods_id,$goods_name,$shop_price,$num=1){
        //判断添加的商品在购物车中是否已经存在
        if($this->hasItem($goods_id)){
            return $this->incNum($goods_id , $num);
        }
        $this->items[$goods_id] = array();//此时items为二维数组
        $this->items[$goods_id]['goods_name'] = $goods_name;
        $this->items[$goods_id]['shop_price'] = $shop_price;
        $this->items[$goods_id]['num'] = $num;
    }

    /**
     * 修改购物车中的商品啊数量
     * @param int $num,某个商品修改后的数量,即直接把某商品的数量改成$num
     */
    public function modNum($goods_id , $num=1){
        if( !$this->hasItem($goods_id) ){
            $this->items[$goods_id]['num'] = $num;
        }else{
            return false;
        }
    }

    /**
     * 购物车中数量增加一个
     */
    public function incNum($goods_id , $num=1){
        if($this->hasItem($goods_id)){
            $this->items[$goods_id]['num']+=$num;
        }
    }

    /**
     * 购物车中数量减一
     * 若商品减少为0了,则把商品从购物车删除
     */
    public function decNum($goods_id , $num=1){
        if($this->hasItem($goods_id)){
            $this->items[$goods_id]['num']-=$num;
        }
        //若减少到数量为0,则把该商品从购物车删除
        if($this->items[$goods_id]['num']<1){
            $this->delItem($goods_id);
        }
    }

    /**
     * 判断某商品是否存在
     * 给到一个goods_id,直接判断该id下的商品是否存在
     */
    public function hasItem($goods_id){
        return array_key_exists($goods_id , $this->items);//判断键是否存在
    }

    /**
     * 删除商品
     * 直接unset掉
     */
    public function delItem($goods_id){
        unset($this->items[$goods_id]);
    }

    /**
     * 查询购物车中商品的种类
     */
    public function getCnt(){
        return count($this->items);
    }

    /**
     * 查询购物车中商品的个数
     */
    public function getNum(){
        if($this->getCnt() == 0){
            return 0;
        }
        $sum = 0;
        foreach($this->items as $v){
            $sum += $v['num'];
        }
        return $sum;
    }

    /**
     *查询购物车中商品的总金额 
     */
    public function getPrice(){
        if($this->getCnt() == 0){
            return 0;
        }
        $price = 0.0;
        foreach($this->items as $v){
            $price += $v['num'] * $v['shop_price'];
        }
        return $price;
    }
    
    /**
     * 返回购物车中的所有商品
     */
    public function  all(){
        return $this->items;
    }

    /**
     * 清空购物车
     * 直接赋值为空,即可清空购物车
     */
    public function clear(){
        $this->items=array();
    }
}

$cart = CartTool::getCart();//获取购物车
if($_GET['test'] == 'add'){
    $cart->addItem(1 , '面包' , 15 , 1);
    echo  'ok';
}else if($_GET['test'] == 'show'){
    print_r($cart->all());
    echo '<br/>';
    echo '共',$cart->getCnt(),'种',$cart->getNum(),'个商品<br/>';
    echo '共',$cart->getPrice(),'元';
}else if($_GET['test'] == 'clear'){
    print_r($cart->clear());
}else{
    print_r($cart);
}