基于Laravel, 使用Redis做购物车

三人行必有我师, 本文出自我的好朋友 葉蕓榕: laravel与Redis开发购物车 的博客

我在这里就不做过多赘述, 只写一些必要的东西

环境准备

  • 使用laravel内置的用户登陆认证系统并再其基础上进行修改
1
2
3
php artisan make:auth

php artisan migrate
  • 安装Redis
1
composer require predis/predis

直接上源码

路由准备

  • /routes/web.php
1
2
3
4
5
6
7
8
9
10
11
# ShopCar Routes

Route::get('shopping/add/{id}', 'ShoppingController@add')->name('shopping.add');

Route::get('shopping/shop_car_info', 'ShoppingController@getShopCarInfo')->name('shopping.shop_car_info');

Route::get('shopping/shop_add/{id}', 'ShoppingController@shopCarAdd')->name('shopping.shop_add');

Route::get('shopping/shop_del/{id}', 'ShoppingController@shopCarDel')->name('shopping.shop_del');

Route::get('shopping/shop_clean/{id}', 'ShoppingController@cleanShopCar')->name('shopping.shop_clean');

前端页面

  • home.blade.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
@extends('layouts.app')

@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">

{{--@include('shared.message')--}}

<div class="card-header">Dashboard</div>

<div class="card-body">
@if (session('status'))
<div class="alert alert-success" role="alert">
{{ session('status') }}
</div>
@endif

You are logged in!
</div>
<div class="card-body">
商品0001<a href="/shopping/add/1">加入购物车</a> <br>
商品0002<a href="/shopping/add/2">加入购物车</a> <br/>
商品0003<a href="/shopping/add/3">加入购物车</a>
</div>

<div class="card-body">
<a href="/shopping/shop_car_info">购物车</a>
</div>
</div>
</div>
</div>
</div>
@endsection

home.blade.php

  • shopcar.blade.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
@extends('layouts.app')

@section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="card">
{{--@include('shared.messages')--}}

<div class="card-body">
@if($allGoodsKey)
@for($i = 0; $i < count($allGoodsKey); $i++)
<p>
商品ID: {{ $allGoodsInfo[$allGoodsKey[$i]]['id'] }} <br>
商品昵称: {{ $allGoodsInfo[$allGoodsKey[$i]]['gname'] }} <br>
商品价格: {{ $allGoodsInfo[$allGoodsKey[$i]]['price'] }} <br>
商品数量: {{ $allGoodsNum[$allGoodsKey[$i]] }} <br>
商品总价: {{ $allGoodsNum[$allGoodsKey[$i]] * $allGoodsInfo[$allGoodsKey[$i]]['price'] }}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

<a href={{ route('shopping.shop_add', $allGoodsInfo[$allGoodsKey[$i]]['id']) }}>+增加</a>&nbsp;&nbsp;
<a href={{ route('shopping.shop_del', $allGoodsInfo[$allGoodsKey[$i]]['id']) }}>-减少</a>&nbsp;&nbsp;
<a href={{ route('shopping.shop_clean', $allGoodsInfo[$allGoodsKey[$i]]['id']) }}>清除</a>&nbsp;&nbsp;
</p>
@endfor

@else
<h2>购物车空空如也~</h2>
@endif
</div>
<div class="card-body">
<a href={{ route('home') }}>去购物</a>
</div>
</div>
</div>
</div>
</div>
@endsection

shopcar.blade.php

后端代码

  • ShoppingController
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Auth;

class ShoppingController extends Controller
{
/**
* 添加商品
* @param $goods_id
* @return \Illuminate\Http\RedirectResponse
*/
public function add($goods_id)
{
$user = Auth::user();

$users_table = Redis::exists('ShoppingCar :' . $user->id);

if ($users_table) {
// 用户表存在
// 检查该商品ID是否存在
$GoodsId = Redis::hexists('ShoppingCar :' . $user->id, $goods_id);

if ($GoodsId) {
// 存在取出该商品数量, 进行+1操作
$num = Redis::hget('ShoppingCar :' . $user->id, $goods_id);
$newNum = $num + 1;

// 修改完之后的保存
Redis::hset('ShoppingCar :' . $user->id, $goods_id, $newNum);
} else {
// 将数量设置为1
Redis::hset('ShoppingCar :' . $user->id, $goods_id, 1);
}
} else {
// 用户表不存在
Redis::hmset('ShoppingCar :' . $user->id, array($goods_id => 1));
}

$goods_info_table = Redis::hexists('GoodsInfo:Goods', $goods_id);

if (!$goods_info_table) {
// 先将商品数组信息取出并转换成Json格式
Redis::hset('GoodsInfo:Goods', $goods_id, json_encode($this->getGoodsInfo($goods_id)));
}

// 通知用户
session()->flash('Success', '添加成功');

return redirect()->route('home');
}

/**
* 获取用户全部商品
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function getShopCarInfo()
{
$user = Auth::user();

$allGoodsKey = Redis::hkeys('ShoppingCar :' . $user->id);

if (null == $allGoodsKey) {
$allGoodsNum = false;
$allGoodsInfo = false;
}

for ($i = 0; $i < count($allGoodsKey); $i++) {
$allGoodsNum[$allGoodsKey[$i]] = Redis::hget('ShoppingCar :' . $user->id, $allGoodsKey[$i]);
$allGoodsInfo[$allGoodsKey[$i]] = json_decode(Redis::hget('GoodsInfo:Goods', $allGoodsKey[$i]), true);
}

return view('shopping_car.shopcar', [
'allGoodsInfo' => $allGoodsInfo,
'allGoodsNum' => $allGoodsNum,
'allGoodsKey' => $allGoodsKey
]);
}

public function getGoodsInfo($goods_id)
{
$GoodsInfo= array(

1 => array(
'id' => 1,
'gname' => 'goods1',
'price' => '1'
),

2 => array(
'id' => 2,
'gname' => 'goods2',
'price' => '2'
),
3 => array(
'id' => 3,
'gname' => 'goods3',
'price' => '3'
),
4 => array(
'id' => 4,
'gname' => 'goods4',
'price' => '4'
),
);

return $GoodsInfo[$goods_id];
}

/**
* 购物车内添加商品
* @param $goods_id
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function shopCarAdd($goods_id)
{
$user = Auth::user();

if (!$user) {
redirect()->route('home');
}

// 取出该商品数
$num = Redis::hget('ShoppingCar :' . $user->id, $goods_id);
$newNum = $num + 1;

// 修改完之后的保存
Redis::hset('ShoppingCar :' . $user->id, $goods_id, $newNum);

$allGoodsKey = Redis::hkeys('ShoppingCar :' . $user->id);

for ($i = 0; $i < count($allGoodsKey); $i++) {
$allGoodsNum[$allGoodsKey[$i]] = Redis::hget('ShoppingCar :' . $user->id, $allGoodsKey[$i]);
$allGoodsInfo[$allGoodsKey[$i]] = json_decode(Redis::hget('GoodsInfo:Goods', $allGoodsKey[$i]), true);
}

return view('shopping_car.shopcar', [
'allGoodsInfo' => $allGoodsInfo,
'allGoodsNum' => $allGoodsNum,
'allGoodsKey' => $allGoodsKey
]);
}

/**
* 购物车内减少商品
* @param $goods_id
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function shopCarDel($goods_id)
{
$user = Auth::user();

if (!$user) {
redirect()->route('home');
}

$goods = Redis::hexists('ShoppingCar :' . $user->id, $goods_id);

if ($goods) {
// 存在; 取出该商品数进行减1操作
$num = Redis::hget('ShoppingCar :' . $user->id, $goods_id);

if ($num > 1) {
$newNum = $num - 1;
Redis::hset('ShoppingCar :' . $user->id, $goods_id, $newNum);
} else {
// 删除指定商品
Redis::hdel('ShoppingCar :' . $user->id, $goods_id);
}
}

$allGoodsKey = Redis::hkeys('ShoppingCar :' . $user->id);

if (null == $allGoodsKey) {
$allGoodsNum = false;
$allGoodsInfo = false;
}

for ($i = 0; $i < count($allGoodsKey); $i++) {
$allGoodsNum[$allGoodsKey[$i]] = Redis::hget('ShoppingCar :' . $user->id, $allGoodsKey[$i]);
$allGoodsInfo[$allGoodsKey[$i]] = json_decode(Redis::hget('GoodsInfo:Goods', $allGoodsKey[$i]), true);
}

return view('shopping_car.shopcar', [
'allGoodsInfo' => $allGoodsInfo,
'allGoodsNum' => $allGoodsNum,
'allGoodsKey' => $allGoodsKey
]);
}

/**
* 清空购物车
* @param $goods_id
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function cleanShopCar($goods_id)
{
$user = Auth::user();
Redis::hdel('ShoppingCar :' . $user->id, $goods_id);

$allGoodsKey = Redis::hkeys('ShoppingCar :' . $user->id);

if (null == $allGoodsKey) {
$allGoodsNum = false;
$allGoodsInfo = false;
}

for ($i = 0; $i < count($allGoodsKey); $i++) {
$allGoodsNum[$allGoodsKey[$i]] = Redis::hget('ShoppingCar :' . $user->id, $allGoodsKey[$i]);
$allGoodsInfo[$allGoodsKey[$i]] = json_decode(Redis::hget('GoodsInfo:Goods', $allGoodsKey[$i]), true);
}

return view('shopping_car.shopcar', [
'allGoodsInfo' => $allGoodsInfo,
'allGoodsNum' => $allGoodsNum,
'allGoodsKey' => $allGoodsKey
]);
}
}

使用到的Redis讲解

  • Redis::exists()

检查给定 key 是否存在。

若 key 存在,返回 1 ,否则返回 0 。

  • Redis::hexists()

查看哈希表 key 中,给定域 field 是否存在。

如果哈希表含有给定域,返回 1 。
如果哈希表不含有给定域,或 key 不存在,返回 0 。

  • Redis::hget()

返回哈希表 key 中给定域 field 的值。

给定域的值。
当给定域不存在或是给定 key 不存在时,返回 nil

  • Redis::hset()

将哈希表 key 中的域 field 的值设为 value
如果 key 不存在,一个新的哈希表被创建并进行 HSET 操作。
如果域 field 已经存在于哈希表中,旧值将被覆盖。

如果 field 是哈希表中的一个新建域,并且值设置成功,返回 1
如果哈希表中域 field 已经存在且旧值已被新值覆盖,返回 0

  • Redis::hmset()

同时将多个 field-value (域-值)对设置到哈希表 key 中。
此命令会覆盖哈希表中已存在的域。
如果 key 不存在,一个空哈希表被创建并执行 HMSET 操作。

如果命令执行成功,返回 OK
key 不是哈希表(hash)类型时,返回一个错误。

  • Redis::hkeys()

返回哈希表 key 中的所有域。

一个包含哈希表中所有域的表。
key 不存在时,返回一个空表。

  • Redis::hdel()

删除哈希表 key 中的一个或多个指定域,不存在的域将被忽略。

被成功移除的域的数量,不包括被忽略的域。

参考

Powered by Hexo and Hexo-theme-hiker

Copyright © 2017 - 2023 Keep It Simple And Stupid All Rights Reserved.

访客数 : | 访问量 :