PHP 源代码通过允许任何用户每 5 秒发出一次请求并使用 Redix 来限制对 API 的访问。
安装 Redis/Redix 客户端:
composer 需要 predis/predis
根据您的操作系统下载 Redix (https://github.com/alash3al/redix/releases),然后启动服务:
./redix_linux_amd64
以下答案表明 Redix 正在侦听 RESP 协议的 6380 端口和 HTTP 协议的 7090 端口。
redix resp 服务器位于:localhost:6380
redix http 服务器位于:localhost:7090
在您的 API 中,将以下代码添加到标头:
<?php
require_once 'class.ratelimit.redix.php';
$rl = new RateLimit();
$waitfor = $rl->getSleepTime($_SERVER['REMOTE_ADDR']);
if ($waitfor>0) {
echo 'Rate limit exceeded, please try again in '.$waitfor.'s';
exit;
}
// Your API response
echo 'API response';
脚本class.ratelimit.redix.php的源码是:
<?php
require_once __DIR__.'/vendor/autoload.php';
Predis\Autoloader::register();
class RateLimit {
private $redis;
const RATE_LIMIT_SECS = 5; // allow 1 request every x seconds
public function __construct() {
$this->redis = new Predis\Client([
'scheme' => 'tcp',
'host' => 'localhost', // or the server IP on which Redix is running
'port' => 6380
]);
}
/**
* Returns the number of seconds to wait until the next time the IP is allowed
* @param ip {String}
*/
public function getSleepTime($ip) {
$value = $this->redis->get($ip);
if(empty($value)) {
// if the key doesn't exists, we insert it with the current datetime, and an expiration in seconds
$this->redis->set($ip, time(), self::RATE_LIMIT_SECS*1000);
return 0;
}
return self::RATE_LIMIT_SECS - (time() - intval(strval($value)));
} // getSleepTime
} // class RateLimit