Laravel 智能验证规则生成器:企业级增强方案
<?phpnamespace App\Services\Validation;use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
use Illuminate\Validation\Rule;
use InvalidArgumentException;class SchemaDrivenValidator
{protected $config;protected $schemaCacheKey = 'database_schema_v2';protected $connection;protected $databaseDriver;protected $customRules = [];protected $ignoreRules = [];protected $tableAliases = [];protected $currentTable;protected $nestedValidators = [];public function __construct(){$this->loadConfig();$this->connection = config('database.default');$this->databaseDriver = config("database.connections.{$this->connection}.driver");}protected function loadConfig(){$this->config = config('validation', ['cache_ttl' => 86400,'auto_relation' => true,'strict_types' => false,'default_string_max' => 255,'password_min_length' => 8,'image_max_size' => 2048,'custom_rules' => [],'ignore_fields' => [],'table_aliases' => [],'type_mappings' => ['int' => 'integer','varchar' => 'string','text' => 'string','datetime' => 'date','timestamp' => 'date','json' => 'array',],'special_field_handlers' => ['email' => ['email'],'phone' => ['phone'],'password' => ['min::password_min_length', 'confirmed'],'image' => ['image', 'mimes:jpg,png,jpeg', 'max::image_max_size'],'_at' => ['date'],'_image' => ['image', 'mimes:jpg,png,jpeg', 'max::image_max_size'],'_avatar' => ['image', 'mimes:jpg,png,jpeg', 'max::image_max_size'],]]);$this->customRules = $this->config['custom_rules'] ?? [];$this->ignoreRules = $this->config['ignore_fields'] ?? [];$this->tableAliases = $this->config['table_aliases'] ?? [];}public function getDatabaseSchema(bool $forceRefresh = false){$cacheKey = $this->schemaCacheKey . '_' . $this->connection;if ($forceRefresh) {Cache::forget($cacheKey);}return Cache::remember($cacheKey, $this->config['cache_ttl'], function () {return $this->fetchDatabaseSchema();});}protected function fetchDatabaseSchema(){switch ($this->databaseDriver) {case 'mysql':return $this->getMysqlSchema();case 'pgsql':return $this->getPostgresSchema();case 'sqlite':return $this->getSqliteSchema();default:throw new InvalidArgumentException("Unsupported database driver: {$this->databaseDriver}");}}protected function getMysqlSchema(){$databaseName = config("database.connections.{$this->connection}.database");$columns = DB::connection($this->connection)->table('information_schema.columns')->select('table_name','column_name','column_comment','data_type','character_maximum_length','is_nullable','column_default','column_type','numeric_precision','numeric_scale','extra')->where('table_schema', $databaseName)->get();$indexes = DB::connection($this->connection)->table('information_schema.statistics')->select('table_name','column_name','index_name','non_unique')->where('table_schema', $databaseName)->get();$foreignKeys = DB::connection($this->connection)->table('information_schema.key_column_usage')->select('table_name','column_name','referenced_table_name','referenced_column_name')->where('table_schema', $databaseName)->whereNotNull('referenced_table_name')->get();return $this->processSchemaData($columns, $indexes, $foreignKeys);}protected function getPostgresSchema(){$schema = config("database.connections.{$this->connection}.schema", 'public');$columns = DB::connection($this->connection)->table('information_schema.columns')->select('table_name','column_name','column_default','is_nullable','data_type','character_maximum_length','numeric_precision','numeri