php搶購秒殺邏輯

2022-08-30 05:36:11 字數 4953 閱讀 6624

1

<?php2/*

*3* 搶購的處理邏輯4*/

56include 'init.php';78

$template['type'] = 'buy';

9$template['pagetitle'] = '搶購';

1011

$active_model = new

\model\active();

12$goods_model = new

\model\goods();

1314

//引數的處理

15$active_id = getreqint('active_id');

16$goods_id = getreqint('goods_id');

17$goods_num = getreqint('goods_num');

18$sign_data = $_post['sign_data'];

19$question_sign = $_post['question_sign'];

20$ask = $_post['ask'];

21$answer = $_post['answer'];

22$action = isset($_post['action']) ? $_post['action'] : false;23

24if ('buy_cart' == $action

) 27

$client_ip =getclientip();

2829

//1 驗證使用者是否登入

30if (!$login_userinfo || !$login_userinfo['uid'])

34$uid = $login_userinfo['uid'];

35$username = $login_userinfo['username'];

36//

2 驗證引數是否正確、合法

37if (!$active_id || !$goods_id

38 || !$goods_num || !$question_sign

) 42

驗證活動狀態資訊

43$status_check = false;44

$str_sign_data = unsignquestion($sign_data

);45

$sign_data_info = json_decode($str_sign_data, true

);46

//時間不能超過當前時間5分鐘,ip和使用者保持不變

47if ($sign_data_info

48 && $sign_data_info['now'] < $now

49 && $sign_data_info['now'] > $now - 300

50 && $sign_data_info['ip'] == $client_ip

51 && $sign_data_info['uid'] == $uid

52)

55if (!$status_check

) 59

驗證問答資訊是否正確

60$question_check = false;61

$str_question = unsignquestion($question_sign

);62

$question_info = json_decode(trim($str_question), true

);63

if ($str_question && $question_info

) 73}74

if (!$question_check

) 78

79//

統一格式化單商品、組合商品的資料結構

80$nums = $goods = array

();81

if ('buy_cart' != $action

) else

8889

$redis_obj = \common\datasource::getredis('instance1');

90$d_list = array

(91 'u_trade_' . $uid . '_' . $active_id,

92 'st_a_' . $active_id

93);

94/**95

* id, sys_status,

96* num_user, num_left,

97* price_normal, price_discount

98*/

99foreach ($goods

as$i => $goods_id

) 102

$data_list = $redis_obj->mget($d_list

);103

//4 驗證使用者是否已經購買

104if ($data_list[0])

108//

5 驗證活動資訊,商品資訊是否正常

109if ($data_list[1])

113unset($data_list[0]);

114unset($data_list[1]);

115/*

116// 4 驗證使用者是否已經購買

117$trade_model = new \model\trade();

118$trade_info = $trade_model->getusertrade($uid, $active_id);

119if ($trade_info)

123// 5 驗證活動資訊,商品資訊是否正常

124$active_info = $active_model->get($active_id);

125if (!$active_info || $active_info['sys_status'] !== '1'

126|| $active_info['time_begin'] > $now

127|| $active_info['time_end'] < $now

128)

132if ('buy_cart' != $action) else

139*/

140$num_total = $price_total = $price_discount = 0;

141$trade_goods = array

();142

foreach ($data_list

as$i => $goods_info

) 149

//6 驗證使用者購買的商品數量是否在限制的範圍內

150if ($goods_num > $goods_info['num_user'])

154//

7 驗證商品是否還有剩餘數量

155if ($goods_info['num_left'] < $goods_num

) 159

//8 扣除商品剩餘數量

160$left = $goods_model->changeleftnumcached($goods_id, 0-$goods_num

);161

$ok = false

;162

if ($left >= 0) else

170171

172//

9.1 建立訂單資訊,訂單的商品資訊

173$trade_goods = array

(174 'goods_info' => $goods_info,

175 'goods_num' => $goods_num

176);

177$num_total += $goods_num

;178

$price_total += $goods_info['price_normal'] * $goods_num

;179

$price_discount += $goods_info['price_discount'] * $goods_num

;180

}181

儲存訂單資訊

182$trade_model = new

\model\trade();

183$trade_info = array

(184 'active_id' => $active_id,

185 'goods_id' => $goods_id,

186 'num_total' => $num_total,

187 'num_goods' => count($goods),

188 'price_total' => $price_total,

189 'price_discount' => $price_discount,

190 'goods_info' => json_encode($trade_goods),

191 'uid' => $uid,

192 'username' => $username,

193 'sys_ip' => $client_ip,

194 'sys_dateline' => $now,

195 'time_confirm' => $now,

196 'sys_status' => 1,

197);

198foreach ($trade_info

as$k => $v

) 201

$trade_id = $trade_model->create();

202if ($trade_id

) 205

206//

10 返回提示資訊

207$result = '秒殺成功,請盡快去支付';

208 show_result($result, '/trade.php');

php使用redis watch秒殺搶購

redis的watch multi exec 方法實現秒殺搶購。優點 使用了樂觀鎖沒有鎖的等待,比佇列方式減少了大量的記憶體消耗。watch 監視乙個或多個key,如果在事務執行之前這個 或這些 key被其他命令所改動,那麼事務將被打斷.redis new redis result redis co...

PHP Redis秒殺搶購

string型別 apache併發請求 c 客戶端 n請求數量 ab.exe c700 n6000 192.168 88.151 82 檔名.php redis new redis redis connect 127.0.0.1 6379 對某乙個鍵加鎖 redis watch sales redi...

php實現秒殺 搶購的訊息佇列

訊息佇列的一般應用場景是搶購,秒殺等等幾分鐘內流量劇增,很容易搞崩系統,佇列可以有效緩解伺服器的壓力 排序保證,接下來就會說一下具體的 實現 訊息佇列 大家可以建立兩個檔案 tolist.php 加入佇列 deal.php 處理佇列 佇列長度限制了10個,如果超過10個的話,則提示稍後再試!需要等d...