| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- <?php
- namespace app\utils;
- use ReflectionClass;
- use ReflectionException;
- /**
- * 智能枚举验证器
- * 自动发现并验证请求参数中的枚举字段
- */
- class EnumUtil
- {
- /**
- * 自动验证请求参数中的枚举字段
- *
- * @param string|object $enumClassOrInstance 枚举类名或实例
- * @param array $requestData 请求数据
- * @return array 验证结果 ['valid' => bool, 'errors' => array]
- */
- public static function autoValidate($enumClassOrInstance, array $requestData): array
- {
- $errors = [];
-
- try {
- $constants = self::getEnumConstants($enumClassOrInstance);
- foreach ($constants as $constName => $enumValues) {
- if (!self::isValidEnumArray($enumValues)) {
- continue;
- }
- $fieldName = self::constToFieldName($constName);
- if (array_key_exists($fieldName, $requestData)) {
- if (empty($requestData[$fieldName])) {
- continue;
- }
- $result = self::validateEnumValue($requestData[$fieldName], $enumValues, $constName);
- if (!$result['valid']) {
- $errors[] = $result['error'];
- }
- }
- }
- } catch (ReflectionException $e) {
- return [
- 'valid' => false,
- 'errors' => ["枚举验证异常: " . $e->getMessage()]
- ];
- }
- return empty($errors) ? [
- 'valid' => true,
- 'errors' => []
- ] : [
- 'valid' => false,
- 'errors' => $errors
- ];
- }
- /**
- * 获取枚举类的所有字段映射
- *
- * @param string|object $enumClassOrInstance 枚举类名或实例
- * @return array 字段映射 [字段名 => 枚举值数组]
- */
- public static function getFieldMappings($enumClassOrInstance): array
- {
- $mappings = [];
-
- try {
- $constants = self::getEnumConstants($enumClassOrInstance);
- foreach ($constants as $constName => $enumValues) {
- if (self::isValidEnumArray($enumValues)) {
- $mappings[self::constToFieldName($constName)] = $enumValues;
- }
- }
- } catch (ReflectionException $e) {
- // 忽略异常,返回空数组
- }
- return $mappings;
- }
- /**
- * 获取枚举类的常量
- *
- * @param string|object $enumClassOrInstance
- * @return array
- * @throws ReflectionException
- */
- private static function getEnumConstants($enumClassOrInstance): array
- {
- return (new ReflectionClass($enumClassOrInstance))->getConstants();
- }
- /**
- * 检查是否为有效的枚举数组(非MAP格式的数组)
- *
- * @param mixed $enumValues
- * @return bool
- */
- private static function isValidEnumArray($enumValues): bool
- {
- return is_array($enumValues) && !empty($enumValues) && !self::isMapFormat($enumValues);
- }
- /**
- * 将枚举常量名转换为字段名
- *
- * @param string $constName 常量名称
- * @return string 字段名
- */
- private static function constToFieldName(string $constName): string
- {
- return strtolower($constName);
- }
- /**
- * 验证单个枚举值
- *
- * @param mixed $value 要验证的值
- * @param array $enumValues 枚举值数组
- * @param string $constName 常量名称
- * @return array 验证结果 ['valid' => bool, 'error' => string|null]
- */
- private static function validateEnumValue($value, array $enumValues, string $constName): array
- {
- $validValues = array_keys($enumValues);
- $normalizedValue = is_numeric($value) ? (int)$value : $value;
-
- if (!in_array($normalizedValue, $validValues, true)) {
- return [
- 'valid' => false,
- 'error' => self::constToFieldName($constName) . "参数错误,值:{$value}"
- ];
- }
- return [
- 'valid' => true,
- 'error' => null
- ];
- }
- /**
- * 检查枚举值数组是否为MAP格式(包含code字段)
- *
- * @param array $enumValues 枚举值数组
- * @return bool
- */
- private static function isMapFormat(array $enumValues): bool
- {
- if (empty($enumValues)) {
- return false;
- }
-
- $firstValue = reset($enumValues);
- return is_array($firstValue) && isset($firstValue['code']);
- }
- }
|