args[0] ?? 'processedEvents'; if (empty($value)) { $this->addError('事件类型不能为空'); return false; } if (!is_array($value)) { $this->addError('事件类型必须是数组格式'); return false; } // 验证事件数量 if (count($value) > 50) { $this->addError('事件类型数量不能超过50个'); return false; } $processedEvents = []; $validEvents = $this->getValidEvents(); foreach ($value as $index => $event) { if (!is_string($event)) { $this->addError("第" . ($index + 1) . "个事件类型必须是字符串"); return false; } $event = trim($event); if (empty($event)) { continue; } // 验证事件格式 if (!$this->validateEventFormat($event)) { return false; } // 验证事件是否有效 if (!$this->isValidEvent($event, $validEvents)) { $this->addError("无效的事件类型: {$event}"); return false; } $processedEvents[] = $event; } // 去重 $processedEvents = array_unique($processedEvents); if (empty($processedEvents)) { $this->addError('至少需要配置一个事件类型'); return false; } // 验证事件组合的合理性 if (!$this->validateEventCombination($processedEvents)) { return false; } // 将处理后的事件列表保存到验证对象中 $this->validation->$processedKey = array_values($processedEvents); return true; } /** * 获取有效的事件类型 * * @return array */ protected function getValidEvents(): array { return [ // 通配符事件 '*', // 用户事件 'user.created', 'user.updated', 'user.deleted', 'user.login', 'user.logout', 'user.password_changed', // 游戏事件 'game.started', 'game.finished', 'game.paused', 'game.resumed', 'game.level_up', 'game.achievement_unlocked', // 物品事件 'item.created', 'item.updated', 'item.deleted', 'item.transferred', 'item.used', 'item.expired', // 资金事件 'fund.deposited', 'fund.withdrawn', 'fund.transferred', 'fund.frozen', 'fund.unfrozen', 'fund.balance_changed', // 交易事件 'trade.created', 'trade.completed', 'trade.cancelled', 'trade.expired', 'trade.disputed', // 系统事件 'system.maintenance', 'system.upgrade', 'system.alert', 'system.backup', // API事件 'api.rate_limit_exceeded', 'api.authentication_failed', 'api.permission_denied', // 应用事件 'app.created', 'app.updated', 'app.suspended', 'app.activated', ]; } /** * 验证事件格式 * * @param string $event * @return bool */ protected function validateEventFormat(string $event): bool { // 通配符事件 if ($event === '*') { return true; } // 事件格式:category.action if (!preg_match('/^[a-z_]+\.[a-z_]+$/', $event)) { $this->addError("事件格式错误: {$event},应为 category.action 格式"); return false; } // 验证长度 if (strlen($event) > 50) { $this->addError("事件名称过长: {$event}"); return false; } return true; } /** * 检查事件是否有效 * * @param string $event * @param array $validEvents * @return bool */ protected function isValidEvent(string $event, array $validEvents): bool { // 直接匹配 if (in_array($event, $validEvents)) { return true; } // 模式匹配(支持通配符) foreach ($validEvents as $validEvent) { if ($this->matchEventPattern($event, $validEvent)) { return true; } } return false; } /** * 事件模式匹配 * * @param string $event * @param string $pattern * @return bool */ protected function matchEventPattern(string $event, string $pattern): bool { // 精确匹配 if ($event === $pattern) { return true; } // 通配符匹配 if ($pattern === '*') { return true; } // 分类通配符匹配(如 user.*) if (str_ends_with($pattern, '.*')) { $category = substr($pattern, 0, -2); return str_starts_with($event, $category . '.'); } return false; } /** * 验证事件组合的合理性 * * @param array $events * @return bool */ protected function validateEventCombination(array $events): bool { // 如果包含通配符,警告可能的性能问题 if (in_array('*', $events)) { $this->addWarning('使用通配符事件(*)会接收所有事件,可能影响性能'); // 如果有通配符,其他事件就没有意义了 if (count($events) > 1) { $this->addWarning('已配置通配符事件(*),其他事件配置将被忽略'); } } // 检查是否有冲突的事件组合 $conflictGroups = [ ['user.created', 'user.deleted'], ['game.started', 'game.finished'], ['fund.deposited', 'fund.withdrawn'], ]; foreach ($conflictGroups as $group) { $foundEvents = array_intersect($events, $group); if (count($foundEvents) === count($group)) { $this->addWarning('配置了相互冲突的事件: ' . implode(', ', $foundEvents)); } } return true; } }