本篇文章是通過ThinkPHP5和Redis實作購物車,功能包括:購物車串列、添加購物車、獲取部分商品、獲取部分商品總數量、獲取全部商品總數量、商品減一、修改商品數量、洗掉商品、清空購物車,這些功能基本上能夠滿足購物車的需求,代碼寫的不夠嚴謹,但大致邏輯就是這樣,
前提:安裝PHP運行環境,安裝Redis,PHP安裝Redis擴展,需要同時滿足以上三個條件才能使用Redis,
參考文章:
- Linux CentOS7 配置LAMP環境
- Linux CentOS7下安裝Redis
- PHP+Redis的使用,Linux下為PHP安裝Redis擴展
一、先看一個運行截圖(主要實作功能,頁面沒有優化)

二、附上代碼
1、前端
<!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8"> </head> <body> <h3>我的購物車</h3> <form action="/index/index/index" method="post"> <input type="text" name="ids"> <input type="submit" value="獲取部分商品資訊"> <span style="color: gray; font-size: 14px;">用英文逗號隔開</span> </form> 所選商品數量:{$totalnum} <br><br> <form action="/index/index/emptyCart"> <input type="submit" value="清空購物車"> </form> <br> <table border="1"> <tr align="center"> <td style="width: 100px">商品ID</td> <td style="width: 100px">商品屬性ID</td> <td style="width: 100px">商品名</td> <td style="width: 100px">商品屬性名稱</td> <td style="width: 100px">數量</td> <td style="width: 100px">單價</td> <td style="width: 100px">運費</td> <td style="width: 100px">總價</td> <td style="width: 100px">操作</td> </tr> {volist name="list" id="vo"} <tr align="center"> <td style="width: 100px">{$vo.goods_id}</td> <td style="width: 100px">{$vo.attr_id}</td> <td style="width: 100px">{$vo.goods_name}</td> <td style="width: 100px">{$vo.attr_name}</td> <td style="width: 100px">{$vo.goods_number}</td> <td style="width: 100px">{$vo.price}</td> <td style="width: 100px">{$vo.freight}</td> <td style="width: 100px">{$vo.subtotal}</td> <td style="width: 100px"><a href="/index/index/del.html?id={$vo.goods_id}">洗掉</a></td> </tr> {/volist} </table> <br/> <hr/> <h3>添加購物車</h3> <form action="/index/index/addbasket" method="post"> 商品ID:<input type="text" name="goods_id" value="111"> 商品屬性ID:<input type="text" name="attr_id" value="222"> 商品名:<input type="text" name="goods_name" value="U盤"> 商品屬性名稱:<input type="text" name="attr_name" value="數碼類"> <br/><br/> 數 量:<input type="text" name="number" value="1"> 單 價:<input type="text" name="price" value="12"> 運 費:<input type="text" name="freight" value="10"> <input type="submit" value="添加購物車"> </form> <br/> <hr/> <h3>某一商品減一</h3> <form action="/index/index/reduce" method="post"> 商品ID:<input type="text" name="id"> 商品屬性ID:<input type="text" name="attr_id"> 減去數量:<input type="text" name="number"> <input type="submit" value="減一"> </form> <br/> <hr/> <h3>編輯商品</h3> <form action="/index/index/edit" method="post"> 商品ID:<input type="text" name="id"> 商品屬性ID:<input type="text" name="attr_id"> 修改數量:<input type="text" name="number"> <input type="submit" value="修改"> </form> <br/> <hr/> </body> </html>
2、后端代碼
<?php namespace app\index\controller; use think\Controller; use think\cache\driver\Redis; class Index extends Controller { private $expire = 43200; //redis快取過期時間 private $redis = null; private $cachekey = null; //快取變數名 private $basket = []; //私有陣列,存放商品資訊 private $user_id = '110';
/** * 購物車初始化,傳入用戶id */ public function __construct() { parent::__construct(); // redis連接引數 $opt['host'] = '127.0.0.1'; $opt['port'] = 6379; $opt['password'] = 'zxf123456'; $this->redis = new Redis($opt); // 實體化 $this->cachekey = 'user'.$this->user_id.'.cart'; //redis快取鍵名拼接用戶id與字串為物件用戶購物車快取鍵名 user110.cart $this->basket = json_decode($this->redis->get($this->cachekey),true); //獲取物件用戶的redis購物車商品快取資訊并解碼為陣列 } /** * 獲取所有商品資訊 */ public function index() { $ids = input('post.ids'); // 如果獲取部分商品資訊(搜索進來) if (!empty($ids)) { // 獲取部分商品資訊 $list = $this->getPartGoods($ids); // 獲取部分商品數量 $totalnum = $this->getPartGoodsNum($ids); }else{ // 默認全部串列 $list = $this->basket; // 獲取所有商品數量 $totalnum = $this->getAllDoodsNum(); } $this->assign(['list'=>$list,'totalnum'=>$totalnum]); return $this->fetch(); } /** * 添加商品到購物車 * @param 商品id 商品屬性id 商品名稱 數量 價格 */ public function addbasket() { $data = request()->param(); // 判斷物件是否已經存在redis購物車快取中 if ($this->isExist($data['goods_id'],$data['attr_id'])) { // 存在快取中,增加該商品數量 return $this->add($data['goods_id'],$data['attr_id'],$data['number']); } // 物件商品不在redis快取中時 $tmp = []; $tmp['goods_id'] = intval($data['goods_id']); //商品id $tmp['attr_id'] = intval($data['attr_id']); //商品屬性id $tmp['goods_name'] = $data['goods_name']; //商品名 $tmp['attr_name'] = $data['attr_name']; //商品屬性名稱 $tmp['goods_number'] = intval($data['number']); //商品數量,新增的商品默認加入數量為1 $tmp['price'] = intval($data['price']); //商品價格 $tmp['freight'] = intval($data['freight']); //運費 $tmp['subtotal'] = $tmp['goods_number'] * $tmp['price'] + $tmp['freight']; //商品總價 $this->basket[] = $tmp; // 把新的商品資訊追加到之前的商品快取陣列中,每件屬性商品對應一個索引鍵值 // 把新的購物車資訊編碼為json字串,并重新存入到redis購物車快取中 // $this->redis->setex($this->cachekey,$this->expire,json_encode($this->basket)); $this->redis->set($this->cachekey,json_encode($this->basket)); // return 1; echo "<script>alert('添加成功');window.location.replace(document.referrer);;</script>"; } /** * 判斷商品是否已經存在 * @param 商品id 商品屬性id */ public function isExist($id,$attr_id) { $isExist = false; // 當物件用戶redis購物車商品快取不為空時 if (!empty($this->basket)) { foreach ($this->basket as $key => $value) { // 判斷當前商品是否存在 if ($value['goods_id'] == $id && $value['attr_id'] == $attr_id) { $isExist = true; break; } } } return $isExist; } /** * 添加商品 */ 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 => $value) { if ($value['goods_id'] == $id && $value['attr_id'] == $attr_id) { // 只修改商品數量和總價 $value['goods_number'] = $value['goods_number'] + $number; //增加購物車商品數量 $value['subtotal'] = $value['goods_number'] * $value['price'] + $value['freight']; //重新計算總價 數量*單價+運費 $this->basket[$key] = $value; //把該商品重新放到redis快取中 $this->redis->set($this->cachekey,json_encode($this->basket)); //更新redis快取 $goods_number = $value['goods_number']; break; } } } return $goods_number; //回傳商品數量 } /** * 獲取部分商品 */ public function getPartGoods($ids) { // 字串轉陣列 $ids = explode(',', $ids); $goods = []; // 回圈ids陣列,回圈redis快取陣列,當商品id一致時,取出來存到goods陣列中 foreach ($ids as $v) { foreach ($this->basket as $key => $value) { if ($value['goods_id'] == $v) { $goods[] = $value; } } } return $goods; } /** * 獲取部分商品總數 */ public function getPartGoodsNum($ids) { // 字串轉陣列 $ids = explode(',', $ids); $number = 0; //默認為0 foreach ($ids as $v) { foreach ($this->basket as $key => $value) { // 取出redis快取中有該id的商品數量 if ($value['goods_id'] == $v) { $number += $value['goods_number']; } } } return $number; } /** * 獲取全部商品數量 */ public function getAllDoodsNum() { $number = 0; if (!empty($this->basket)) { foreach ($this->basket as $key => $value) { $number += $value['goods_number']; } } return $number; } /** * 某一商品數量減一 */ public function reduce() { $data = request()->param(); $goods_number = 0; //默認減0 // 如果接收的資料不為空,并且該商品資訊存在 if (!empty($data) && $this->isExist($data['id'],$data['attr_id'])) { // 獲取redis快取里的資料 $cache_detail = $this->basket; // 回圈判斷,從快取商品串列中找到該條商品,數量并減一 foreach ($cache_detail as $key => $value) { if ($value['goods_id'] == $data['id'] && $value['attr_id'] == $data['attr_id']) { // 先判斷當前商品的數量是否大于要洗掉的數量 if ($value['goods_number'] < $data['number']) { echo "<script>alert('商品數量不足');window.history.back();</script>"; break; } // 如果當前商品數量為1,則洗掉 if ($value['goods_number'] <= 1) { // 回圈判斷找出該商品,并洗掉 foreach ($this->basket as $key => $value) { if ($value['goods_id'] == $data['id']) { // 從陣列中移除當前商品 array_splice($this->basket, $key, 1); } } // 重新存入快取 $this->redis->set($this->cachekey,json_encode($this->basket)); $goods_number = 0; }else{ // 數量減 $value['goods_number'] = $value['goods_number'] - $data['number']; $goods_number = $value['goods_number']; // 計算總價 $value['subtotal'] = $value['goods_number'] * $value['price']; // 把新的資料追加到$this->basket $this->basket[$key] = $value; // 重新存入快取 $this->redis->set($this->cachekey,json_encode($this->basket)); } } } } // return $goods_number; echo "該商品當前數量為".$goods_number; } /** * 洗掉商品 */ public function del() { $id = input('id'); // 回圈判斷,并洗掉 foreach ($this->basket as $key => $value) { if ($value['goods_id'] == $id) { // 從陣列中移除當前商品 array_splice($this->basket, $key, 1); } } $this->redis->set($this->cachekey,json_encode($this->basket)); // return true; echo "<script>alert('洗掉成功');window.location.replace(document.referrer);;</script>"; } /** * 編輯商品 */ public function edit() { $data = input('post.'); if (!empty($data) && $this->isExist($data['id'],$data['attr_id']) && $data['number'] > 0) { // 取出快取中的資料 $cache_detail = $this->basket; // 回圈判斷,取出當前商品資訊,并修改 foreach ($cache_detail as $key => $value) { if ($value['goods_id'] == $data['id'] & $value['attr_id'] == $data['attr_id']) { // 商品數量 $value['goods_number'] = intval($data['number']); // 商品總價 數量*單價+運費 $value['subtotal'] = $value['goods_number'] * $value['price'] + $value['freight']; // 賦值 $this->basket[$key] = $value; // 重新存盤到快取 $this->redis->set($this->cachekey,json_encode($this->basket)); echo "該商品當前數量為".$value['goods_number']; } } } } /** * 清空購物車 */ public function emptyCart() { $this->redis->rm($this->cachekey); echo "<script>alert('購物車清空成功');window.location.replace(document.referrer);;</script>"; } }
有一點需要注意:“use think\cache\driver\Redis;”把redis引進來,這個Redis檔案是TP5自帶的,不用下載就可以直接用,代碼里有注釋,其他的就不再說明了,其他檔案也沒有什么需求配置的
TP5自帶的Redis.php檔案函式較少,如果直接使用TP5自帶的redis,有些函式是不能用的,如果想使用更多的函式,需要連接外部的redis
三、常見錯誤
列一下我在使用程序中遇到的問題
- 在“清空購物車”這個功能里,有一句“ $this->redis->rm($this->cachekey);”,執行這句的時候會報錯,"Function Redis::delete() is deprecated",意思是delete()這個函式已經被棄用了,可以查找到Redis檔案里rm()這個函式,里面用到了delete()這個函式,只需要把delete()改成del就可以了,因為php-redis 5 已經把這個函式棄用了

其他棄用函式

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/238673.html
標籤:其他
上一篇:如何寫出讓同事無法維護的代碼?
下一篇:Java字串相關面試題
