<?php
//本脚本依赖 php-redis扩展,请自行安装
//商品
class Good {
//名字
protected $name;
//商品id
protected $id;
//库存
protected $stock;
public function __construct(string $name, int $id, int $stock = 0)
{
$this->name = $name;
$this->id = $id;
$this->stock = $stock;
}
public function __get(string $name)
{
if ($this->{$name})
{
return $this->{$name};
}
throw new \Exception('method not exists :'.$name);
// TODO: Implement __get() method.
}
/**增加库存
* @param int $count
* @return int
*/
public function addStock(int $count) : int
{
if ($count > 0)
$this->stock += $count;
return $this->stock;
}
/**减少库存
* @param int $count
* @return int
*/
public function downStock(int $count) : int
{
if ($count > 0)
$this->stock -= $count;
return $this->stock;
}
/**设置商品库存
* @param int $count
* @return true
*/
public function setStock(int $count) : int
{
if ($count >= 0)
$this->stock = $count;
return true;
}
}
class User {
//用户id
protected $id;
//用户名字
protected $name;
public function __construct(int $id, string $name)
{
$this->id = $id;
$this->name = $name;
}
public function __get(string $name)
{
if ($this->{$name})
{
return $this->{$name};
}
throw new \Exception('method not exists :'.$name);
// TODO: Implement __get() method.
}
}
interface Cart {
public function buy();
}
//ACT 抢购
class Act implements Cart{
protected $redis;
protected $user;
protected $good;
public function __construct(User $user, Good $good, Redis $redis)
{
$this->redis = $redis;
$this->user = $user;
$this->good = $good;
}
//商品队列键
public function getGoodRedisKey()
{
return 'GOOD_CART_'.$this->good->id;
}
//用户hash
public function getUserRedisKey()
{
return 'USER_CART';
}
//初始化商品库存到redis
public function addGoodStockToRedis()
{
$stock = $this->good->stock;
if (
$stock > 0
&& $this->getRedisGoodStock() <= 0
) {
for ($i = 0; $i < $stock; $i++)
{
$this->redis->lPush($this->getGoodRedisKey(), 1);
}
}
}
//获取redis的商品库存数量
public function getRedisGoodStock()
{
return $this->redis->lLen($this->getGoodRedisKey());
}
/**判断用户是否已经参与抢购了
* @return bool true为未参与
*/
public function userNotBuy()
{
$key = $this->getUserRedisKey();
return !!$this->redis->hSet($key, $this->user->id, 1);
}
/**
* 用户抢购,减少商品库存
* @return bool true为抢购成功
*/
public function downGoodStock()
{
//redis减少库存, 并且设置商品库存数量
return
$this->redis->lPop($this->getGoodRedisKey())
&& $this->good->setStock($this->getRedisGoodStock());
}
public function buy()
{
//初始化库存到redis
$this->addGoodStockToRedis();
//如果用户没有参与抢购
if ($this->userNotBuy())
{
//抢购成功与否
return $this->downGoodStock();
}
}
}
$total = 10;
$good = new Good('棒棒糖', '5', $total);
$redis = new Redis();
$redis->connect('127.0.0.1');
//模拟多个用户
while($total)
{
$rand = rand(1, $total);
$user = new User($rand, 'user'.$rand);
$activity = new Act($user, $good, $redis);
if ($activity->buy())
{
echo <<<str
用户: {$user->name} 抢购成功;<br>
商品剩余库存:{$good->stock} <br>
str;
} else
{
echo '抢购失败';
break;
}
$total = $good->stock;
unset($user, $activity);
}
?>