Files
docs/thinkphp/app/middleware/RateLimit.php
cenzuhai 3a04eede84 feat: 初始化进销存数据开放平台项目
初始化完整的前后端项目结构,包含ThinkPHP后端API服务和Next.js前端管理系统,添加基础配置、中间件、模型、路由等核心代码,以及项目文档和静态资源。
2026-07-08 17:48:00 +08:00

68 lines
1.7 KiB
PHP

<?php
namespace app\middleware;
use think\facade\Cache;
use think\Request;
class RateLimit
{
public function handle(Request $request, \Closure $next)
{
$authContext = $request->authContext ?? null;
if (!$authContext) {
return $next($request);
}
$apiKeyId = $authContext['api_key_id'];
$limitPerMinute = $authContext['rate_limit_per_minute'] ?? 60;
$limitPerDay = $authContext['rate_limit_per_day'] ?? 5000;
$minuteKey = 'rate_limit:minute:' . $apiKeyId;
$dayKey = 'rate_limit:day:' . $apiKeyId . ':' . date('Ymd');
$minuteCount = $this->getCount($minuteKey);
if ($minuteCount >= $limitPerMinute) {
return json([
'code' => 429,
'msg' => '请求过于频繁,请稍后再试'
], 429);
}
$dayCount = $this->getCount($dayKey);
if ($dayCount >= $limitPerDay) {
return json([
'code' => 429,
'msg' => '今日请求次数已达上限'
], 429);
}
$this->increment($minuteKey, 60);
$this->increment($dayKey, 86400);
return $next($request);
}
private function getCount($key)
{
try {
$value = Cache::get($key);
return $value !== false ? (int)$value : 0;
} catch (\Exception $e) {
return 0;
}
}
private function increment($key, $ttl)
{
try {
$current = $this->getCount($key);
$newValue = $current + 1;
Cache::set($key, $newValue, $ttl);
return $newValue;
} catch (\Exception $e) {
return 1;
}
}
}