use Predis\Client;
/**
* Created by PhpStorm.
* User: shichaopeng
* Date: 2018/10/20
* Time: 17:44
*/
class RateLimiter {
private $client;
private $name;
private $maxCallsPerHour;
private $slidingWindow;
/**
* RateLimiter constructor.
* @param $client
* @param $name
* @param $maxCallsPerHour
* @param $slidingWindow
*/
public function __construct(Client $client, $name, $maxCallsPerHour, $slidingWindow) {
$this->client = $client;
$this->name = $name;
$this->maxCallsPerHour = $maxCallsPerHour;
$this->slidingWindow = $slidingWindow;
}
public function remaining() {
$now = microtime(true);
$accessToken = md5($this->name);
$this->client->multi();
$this->client->zrangebyscore($accessToken, 0, $now - $this->slidingWindow);
$this->client->zrange($accessToken, 0, -1);
$this->client->zadd($accessToken, $now, $now);
$this->client->expire($accessToken, $this->slidingWindow);
$result = $this->client->exec();
$timestamps = $result[1];
$remaining = max(0, $this->maxCallsPerHour - count($timestamps));
return $remaining > 0;
}
// /**
// * @param $key
// * @param int $limit
// * @param int $expire
// * @return bool
// */
// function rate_limit($key, $limit = 10, $expire = 1) {
// $redis = createRedisCli();
// // 获取当前的计数器的值
// $current = $redis->get($key);
// // 如果当前计数器的值存在且计数器已经超过限制,返回失败
// if ($current != null && $current >= $limit) {
// return false;
// } else {
// // 获取计数器的存活时间
// $ttl = $redis->ttl($key);
// // 开始一个事务 // 命名为op2(操作2)
// $redis->multi(Redis::MULTI);
// // 将计数器原子加1,若计数器不存在,则创建计数器
// $redis->incr($key);
// // 若存活时间小于0,代表计数器之前不存在,是刚刚创建的,则设置一个存活时间
// if ($ttl < 0) {
// $redis->expire($key, $expire);
// }
// // 提交事务
// $redis->exec();
// return true;
// }
// }
}