diff --git a/README.md b/README.md index 6011aa6..ee29c45 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ php-ratelimiter =============== -A small class that uses Memcache to allow only a certain number of requests per a certain amount of minutes. +> NOTE: this was previously working with memcache, but I adjusted it to work with memcached (with a d). + +A small class that uses Memcached to allow only a certain number of requests per a certain amount of minutes. The class works around the problem that the timeframe is constantly moving, i.e. every new minute the timeframe is different. See my [blogpost](http://alexander.kirk.at/2013/04/19/add-a-rate-limit-to-your-website/). @@ -11,7 +13,7 @@ Usage ----- ```php -$rateLimiter = new RateLimiter(new Memcache(), $_SERVER["REMOTE_ADDR"]); +$rateLimiter = new RateLimiter($_SERVER["REMOTE_ADDR"]); try { // allow a maximum of 100 requests for the IP in 5 minutes $rateLimiter->limitRequestsInMinutes(100, 5); @@ -30,10 +32,10 @@ If you want to protect multiple resources with different limits, use the third p ```php // script1.php -$rateLimiter = new RateLimiter(new Memcache(), $_SERVER["REMOTE_ADDR"], "script1"); +$rateLimiter = new RateLimiter($_SERVER["REMOTE_ADDR"], "script1"); try { ... } // script2.php -$rateLimiter = new RateLimiter(new Memcache(), $_SERVER["REMOTE_ADDR"], "script2"); +$rateLimiter = new RateLimiter($_SERVER["REMOTE_ADDR"], "script2"); try { ... } ``` diff --git a/ratelimiter.php b/ratelimiter.php index 24bb875..8c2e5fe 100644 --- a/ratelimiter.php +++ b/ratelimiter.php @@ -27,9 +27,10 @@ class RateExceededException extends Exception {} class RateLimiter { - private $prefix, $memcache; - public function __construct(Memcache $memcache, $ip, $prefix = "rate") { - $this->memcache = $memcache; + private $prefix, $memcached; + public function __construct($ip, $prefix = "rate", $port=11211) { + $this->memcached = new Memcached(); + $this->memcached->addServer('localhost', $port); $this->prefix = $prefix . $ip; } @@ -37,21 +38,21 @@ public function limitRequestsInMinutes($allowedRequests, $minutes) { $requests = 0; foreach ($this->getKeys($minutes) as $key) { - $requestsInCurrentMinute = $this->memcache->get($key); + $requestsInCurrentMinute = $this->memcached->get($key); if (false !== $requestsInCurrentMinute) $requests += $requestsInCurrentMinute; } if (false === $requestsInCurrentMinute) { - $this->memcache->set($key, 1, 0, $minutes * 60 + 1); + $this->memcached->set($key, 1, ($minutes + 1) * 60); } else { - $this->memcache->increment($key, 1); + $this->memcached->increment($key); } if ($requests > $allowedRequests) throw new RateExceededException; } private function getKeys($minutes) { - $keys = array(); + $keys = []; $now = time(); for ($time = $now - $minutes * 60; $time <= $now; $time += 60) { $keys[] = $this->prefix . date("dHi", $time); @@ -60,3 +61,4 @@ private function getKeys($minutes) { return $keys; } } +