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...