D7net
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
proc
/
self
/
root
/
opt
/
psa
/
admin
/
plib
/
modules
/
mfa
/
vendor
/
palepurple
/
rate-limit
/
src
/
Filename :
RateLimit.php
back
Copy
<?php namespace PalePurple\RateLimit; /** * @author Peter Chung <touhonoob@gmail.com> * @date May 16, 2015 */ class RateLimit { /** * * @var string */ protected $name; /** * * @var int */ protected $maxRequests; /** * * @var int */ protected $period; /** * @var Adapter */ private $adapter; /** * RateLimit constructor. * @param string $name - prefix used in storage keys. * @param int $maxRequests * @param int $period seconds * @param Adapter $adapter - storage adapter */ public function __construct($name, $maxRequests, $period, Adapter $adapter) { $this->name = $name; $this->maxRequests = $maxRequests; $this->period = $period; $this->adapter = $adapter; } /** * Rate Limiting * http://stackoverflow.com/a/668327/670662 * @param string $id * @param float $use * @return boolean */ public function check($id, $use = 1.0) { $rate = $this->maxRequests / $this->period; $t_key = $this->keyTime($id); $a_key = $this->keyAllow($id); if (!$this->adapter->exists($t_key)) { // first hit; setup storage; allow. $this->adapter->set($t_key, time(), $this->period); $this->adapter->set($a_key, ($this->maxRequests - $use), $this->period); return true; } $c_time = time(); $time_passed = $c_time - $this->adapter->get($t_key); $this->adapter->set($t_key, $c_time, $this->period); $allowance = $this->adapter->get($a_key); $allowance += $time_passed * $rate; if ($allowance > $this->maxRequests) { $allowance = $this->maxRequests; // throttle } if ($allowance < $use) { // need to wait for more 'tokens' to be in the bucket. $this->adapter->set($a_key, $allowance, $this->period); return false; } $this->adapter->set($a_key, $allowance - $use, $this->period); return true; } /** * @deprecated use getAllowance() instead. * @param string $id * @return int */ public function getAllow($id) { return $this->getAllowance($id); } /** * Get allowance left. * * @param string $id * @return int number of requests that can be made before hitting a limit. */ public function getAllowance($id) { $this->check($id, 0.0); $a_key = $this->keyAllow($id); if (!$this->adapter->exists($a_key)) { return $this->maxRequests; } return (int) max(0, floor($this->adapter->get($a_key))); } /** * Purge rate limit record for $id * @param string $id * @return void */ public function purge($id) { $this->adapter->del($this->keyTime($id)); $this->adapter->del($this->keyAllow($id)); } /** * @return string * @param string $id */ private function keyTime($id) { return $this->name . ":" . $id . ":time"; } /** * @return string * @param string $id */ private function keyAllow($id) { return $this->name . ":" . $id . ":allow"; } /** * @param string $name * @return void */ public function setName($name) { $this->name = $name; } /** * @param int $maxRequests * @return void */ public function setMaxRequests($maxRequests) { $this->maxRequests = $maxRequests; } /** * @param int $period * @return void */ public function setPeriod($period) { $this->period = $period; } /** * @param Adapter $adapter * @return void */ public function setAdapter(Adapter $adapter) { $this->adapter = $adapter; } }