在ThinkPHP(TP)框架中處理API限流,可以通過以下幾種方法實(shí)現(xiàn):
ThinkPHP提供了多種緩存驅(qū)動(dòng),如Redis、Memcached等。你可以使用這些緩存系統(tǒng)來(lái)存儲(chǔ)API請(qǐng)求的計(jì)數(shù)器。以下是一個(gè)使用Redis緩存實(shí)現(xiàn)API限流的示例:
首先,確保已經(jīng)安裝并配置了Redis緩存。然后,在application
目錄下創(chuàng)建一個(gè)名為common.php
的文件(如果已經(jīng)存在,跳過此步驟),并添加以下代碼:
use think\facade\Cache;
use think\facade\Request;
// 獲取當(dāng)前請(qǐng)求的路由信息
$routeInfo = Request::routeInfo();
$apiName = $routeInfo['rule']; // 假設(shè)API名稱與路由規(guī)則相同
// 從緩存中獲取API請(qǐng)求計(jì)數(shù)器
$counterKey = 'api_limit:' . $apiName;
$counter = Cache::get($counterKey, 0);
// 設(shè)置限流參數(shù)
$limit = 10; // 每分鐘最多允許10次請(qǐng)求
$interval = 60; // 時(shí)間間隔(秒)
if ($counter >= $limit) {
// 超出限制,返回錯(cuò)誤信息
return json(['code' => 429, 'msg' => '請(qǐng)求過于頻繁,請(qǐng)稍后再試']);
} else {
// 未超出限制,計(jì)數(shù)器加1
Cache::inc($counterKey);
// 設(shè)置計(jì)數(shù)器過期時(shí)間
Cache::set($counterKey, $counter + 1, $interval);
}
有一些第三方庫(kù)可以幫助你實(shí)現(xiàn)API限流,例如overtrue/throttle
。首先,通過Composer安裝該庫(kù):
composer require overtrue/throttle
然后,在application
目錄下創(chuàng)建一個(gè)名為middleware.php
的文件(如果已經(jīng)存在,跳過此步驟),并添加以下代碼:
<?php
use Overtrue\Throttle\Throttle;
use think\facade\Cache;
use think\facade\Request;
// 創(chuàng)建一個(gè)限流器實(shí)例
$throttle = new Throttle(new Cache());
// 設(shè)置限流參數(shù)
$limit = 10; // 每分鐘最多允許10次請(qǐng)求
$interval = 60; // 時(shí)間間隔(秒)
// 獲取當(dāng)前請(qǐng)求的路由信息
$routeInfo = Request::routeInfo();
$apiName = $routeInfo['rule']; // 假設(shè)API名稱與路由規(guī)則相同
// 檢查請(qǐng)求是否超出限制
if (!$throttle->attempt($apiName, $limit, $interval)) {
// 超出限制,返回錯(cuò)誤信息
return json(['code' => 429, 'msg' => '請(qǐng)求過于頻繁,請(qǐng)稍后再試']);
}
你還可以使用ThinkPHP的中間件功能來(lái)實(shí)現(xiàn)API限流。首先,在application
目錄下創(chuàng)建一個(gè)名為middleware
的文件夾(如果已經(jīng)存在,跳過此步驟),然后在該文件夾中創(chuàng)建一個(gè)名為ApiLimit.php
的文件,并添加以下代碼:
<?php
namespace app\middleware;
use think\facade\Cache;
use think\facade\Request;
class ApiLimit
{
public function handle($request, \Closure $next)
{
// 獲取當(dāng)前請(qǐng)求的路由信息
$routeInfo = Request::routeInfo();
$apiName = $routeInfo['rule']; // 假設(shè)API名稱與路由規(guī)則相同
// 從緩存中獲取API請(qǐng)求計(jì)數(shù)器
$counterKey = 'api_limit:' . $apiName;
$counter = Cache::get($counterKey, 0);
// 設(shè)置限流參數(shù)
$limit = 10; // 每分鐘最多允許10次請(qǐng)求
$interval = 60; // 時(shí)間間隔(秒)
if ($counter >= $limit) {
// 超出限制,返回錯(cuò)誤信息
return json(['code' => 429, 'msg' => '請(qǐng)求過于頻繁,請(qǐng)稍后再試']);
} else {
// 未超出限制,計(jì)數(shù)器加1
Cache::inc($counterKey);
// 設(shè)置計(jì)數(shù)器過期時(shí)間
Cache::set($counterKey, $counter + 1, $interval);
}
return $next($request);
}
}
接下來(lái),在config
目錄下的middleware.php
文件中,將新創(chuàng)建的中間件添加到全局中間件列表中:
return [
// ...
'app\middleware\ApiLimit',
];
現(xiàn)在,你已經(jīng)成功地在ThinkPHP框架中實(shí)現(xiàn)了API限流功能。請(qǐng)根據(jù)實(shí)際需求調(diào)整限流參數(shù)和緩存驅(qū)動(dòng)。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。