args[0] ?? 'processedRateLimits'; if (empty($value)) { // 使用默认配置 $value = $this->getDefaultRateLimits(); } if (!is_array($value)) { $this->addError('频率限制配置必须是数组格式'); return false; } $processedLimits = []; $validTypes = $this->getValidLimitTypes(); foreach ($value as $type => $limit) { // 验证限制类型 if (!in_array($type, $validTypes)) { $this->addError("无效的限制类型: {$type}"); return false; } // 验证限制值 if (!$this->validateLimitValue($type, $limit)) { return false; } $processedLimits[$type] = (int)$limit; } // 验证限制值的合理性 if (!$this->validateLimitReasonableness($processedLimits)) { return false; } // 将处理后的配置保存到验证对象中 $this->validation->$processedKey = $processedLimits; return true; } /** * 获取有效的限制类型 * * @return array */ protected function getValidLimitTypes(): array { return [ 'requests_per_minute', 'requests_per_hour', 'requests_per_day', 'requests_per_week', 'requests_per_month' ]; } /** * 获取默认频率限制配置 * * @return array */ protected function getDefaultRateLimits(): array { return [ 'requests_per_minute' => 60, 'requests_per_hour' => 1000, 'requests_per_day' => 10000, 'requests_per_week' => 50000, 'requests_per_month' => 200000, ]; } /** * 验证限制值 * * @param string $type * @param mixed $limit * @return bool */ protected function validateLimitValue(string $type, mixed $limit): bool { if (!is_numeric($limit)) { $this->addError("限制值必须是数字: {$type}"); return false; } $limit = (int)$limit; if ($limit < 0) { $this->addError("限制值不能为负数: {$type}"); return false; } // 验证最大限制值 $maxLimits = [ 'requests_per_minute' => 10000, 'requests_per_hour' => 100000, 'requests_per_day' => 1000000, 'requests_per_week' => 5000000, 'requests_per_month' => 20000000, ]; if (isset($maxLimits[$type]) && $limit > $maxLimits[$type]) { $this->addError("限制值过大: {$type} 最大值为 {$maxLimits[$type]}"); return false; } return true; } /** * 验证限制值的合理性 * * @param array $limits * @return bool */ protected function validateLimitReasonableness(array $limits): bool { // 验证时间单位之间的合理性 $timeUnits = [ 'requests_per_minute' => 1, 'requests_per_hour' => 60, 'requests_per_day' => 1440, 'requests_per_week' => 10080, 'requests_per_month' => 43200, // 30天 ]; foreach ($limits as $type => $limit) { if (!isset($timeUnits[$type])) { continue; } $perMinute = $limit / $timeUnits[$type]; // 检查是否有更短时间单位的限制 foreach ($timeUnits as $shorterType => $shorterMultiplier) { if ($shorterMultiplier >= $timeUnits[$type]) { continue; } if (isset($limits[$shorterType])) { $shorterPerMinute = $limits[$shorterType] / $shorterMultiplier; if ($perMinute > $shorterPerMinute) { $this->addError("限制配置不合理: {$type} 的平均速率不能超过 {$shorterType}"); return false; } } } } return true; } }