symfony/options-resolver
Symfony OptionsResolver enhances array_replace with a robust options system: define required options, set defaults, validate types and values, and normalize inputs. Ideal for building configurable APIs, form components, and reusable libraries with strict option handling.
config() helpers) while addressing gaps in nested/conditional validation and normalization. It integrates seamlessly with Laravel’s Service Container and Dependency Injection, enabling resolved options to be injected directly into services.setDefaults(), setRequired(), setNormalizer()) aligns with Laravel’s philosophy of explicit, readable configuration.HttpClient, Process), this provides consistency in configuration patterns.array_merge logic in service constructors.config() array merging with structured, validated configurations (e.g., config('services.stripe') resolved via OptionsResolver).setDefault() for nested options in v8.0).array_replace Logic: Replacing ad-hoc array merging with OptionsResolver requires refactoring, but the payoff (validation, normalization) is significant.array_replace_recursive, the resolver’s explicit setOptions() method for nested structures may require adjustments.ConfigResolver) to simplify Laravel integration?resolveStripeConfig()) to encapsulate resolver logic?$this->app->singleton(OptionsResolver::class, fn() => new OptionsResolver());
public function rules()
{
$resolved = resolve(OptionsResolver::class)->resolve($this->all());
return ['timeout' => 'required|integer', ...];
}
config('services.stripe') with a resolved object:
$stripeConfig = resolve(StripeConfigResolver::class)->resolve(config('services.stripe'));
public function handle()
{
$options = resolve(OptionsResolver::class)->resolve($this->options);
// Use $options->timeout, etc.
}
OptionsResolver:
// Before
$config = array_replace([
'timeout' => 30,
'endpoint' => 'https://api.example.com',
], $userInput);
// After
$resolver = new OptionsResolver();
$resolver->setDefaults(['timeout' => 30])
->setRequired(['endpoint'])
->setAllowedTypes('timeout', 'int');
$config = $resolver->resolve($userInput);
DatabaseConfigResolver, CacheConfigResolver).class DatabaseConfigResolver
{
public function __invoke(array $config): array
{
$resolver = new OptionsResolver();
$resolver->setDefaults([
'driver' => 'mysql',
'host' => 'localhost',
'port' => 3306,
]);
$resolver->setAllowedValues('driver', ['mysql', 'pgsql', 'sqlite']);
return $resolver->resolve($config);
}
}
$resolver->setDeprecated('old_key', 'new_key');
array_replace_recursive logic may need refactoring to use setOptions() for nested structures (v8.0+).OptionsResolver.OptionsResolver (e.g., "Always use for third-party API configs").How can I help you explore Laravel packages today?