<?php header('content-type:text/html;charset=utf-8'); class SeckillRedis { static protected $validity_time = 300; // 有效期 5分鐘 protected $goods_id; protected $user_queue_key; protected $goods_number_key; protected $user_id; public function __construct($goods_id,$area_id,$uid){ if($goods_id){ $this->goods_id=$goods_id; //當前商品隊列的用戶狀況 $this->user_queue_key="goods_".$goods_id."_user"; //當前商品的庫存隊列 $this->goods_number_key="goods_".$goods_id; } $this->user_id=$uid ? $uid : 2; } /* redis連接 */ static public function getRedis(){ $redis=new Redis(); $redis->connect('127.0.0.1','6379') or die('Can not Content Redis'); if($redis){ return $redis; }else{ die('Can not Content Redis!'); } } // 添加或改變庫存時初始化隊列 public function kuCun($num){ $redis=$this->getRedis(); $redis->delete($this->goods_number_key); // $redis->delete($this->user_queue_key); for ($i=0; $i < $num; $i++) { $redis->rPush($this->goods_number_key, 1); } } // 判斷未支付訂單是否過時 ,定時更新秒殺商品入口人數 public function poling_set_seckill_redis(){ //exists檢查key是否存在,存在返回1,不存在返回0,0也屬於不存在的 if($redis->exists($this->user_queue_key) == true){ // 清除過時的使用數量 $use_list = $redis->lRange($this->user_queue_key, 0, -1); // var_dump($use_list); foreach ($use_list as $k => $v) { $data = json_decode($v, true); if(time() - $data['time'] > self::$validity_time){ // 超過有效期 刪除 $this->returnFree($k,$data['uid']); } } } } /* 獲取空閒搶購--type:50 100 500 1000 */ public function getFree(){ if(empty($this->user_id)){ return array('result' => false, 'message' => '搶購信息:用戶ID不能爲空'); } $redis = self::getRedis(); $result = $redis->lPop($this->goods_number_key); // var_dump($redis->lrange($seckill_array[$type]['free_key'],0,-1)); if($result == true){ // 添加使用數量 $index = $redis->rPush($this->user_queue_key, json_encode(array('uid' => $this->user_id, 'time' => time()))) - 1; return array('result' => true, 'index' => $index); }else{ return array('result' => false, 'message' => '搶購信息:被搶光啦'); } } /* 返回空閒搶購--$index爲鍵值 */ public function returnFree($index,$uid){ $redis = self::getRedis(); $value = $redis->lGet($this->user_queue_key,$index); if(!empty($value)){ $redis->lRem($this->user_queue_key, $value, 1); // 添加空閒數量 $redis->rPush($this->goods_number_key, 1); // $sql語句,庫存加1 return array('result' => true); }else{ return array('result' => false, 'message' => '搶購信息:不存在索引'); } } } class Index{ /* 某個須要控制併發的控制器方法 */ public function getOrderInfo(){ $miaosha=new SeckillRedis('3','123','2'); // $miaosha->kuCun('100'); $result = $miaosha->getFree(); return $result; if($result['result'] == false){ // 沒有機會 返回錯誤信息 return '網絡繁忙,請重試'; } // 處理數據庫代碼 } } $hua = new Index; var_dump($hua->getOrderInfo()).'<br>'; $redis=SeckillRedis::getRedis(); echo $redis->llen('goods_3'); var_dump($redis->lrange('goods_3',0,-1)); var_dump($redis->lrange('goods_3_user',0,-1));
尚在改進,若是有改進或者其餘見解請留言,一同探討php