Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Set Config Resolver Laravel Package

symplify/set-config-resolver

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require symplify/set-config-resolver
    

    Ensure symfony/console and symfony/dependency-injection are also installed (required dependencies).

  2. Basic CLI Integration: In your Laravel Artisan command or CLI entry point (e.g., app/Console/Kernel.php or a custom bin/console script):

    use Symfony\Component\Console\Input\ArgvInput;
    use Symplify\SetConfigResolver\SetAwareConfigResolver;
    use YourApp\Config\YourSetProvider; // Implement SetProviderInterface
    
    $setProvider = new YourSetProvider();
    $configResolver = new SetAwareConfigResolver($setProvider);
    
    // Resolve from CLI --config flag or fallback to a default config file
    $inputConfig = $configResolver->resolveFromInputWithFallback(
        new ArgvInput(),
        ['config/default.php']
    );
    
    if ($inputConfig !== null) {
        config($inputConfig); // Merge into Laravel's config
    }
    
  3. First Use Case: Create a config file (e.g., config/my-tool.php) with a simple array:

    return [
        'my_tool' => [
            'option1' => 'value1',
            'option2' => 'value2',
        ],
    ];
    

    Run your CLI tool with:

    php artisan my:tool --config=config/my-tool.php
    

    Or use a --set flag if your YourSetProvider supports it:

    php artisan my:tool --set=my-set
    

Implementation Patterns

Usage Patterns

  1. CLI-Driven Configuration:

    • Use resolveFromInputWithFallback() to handle --config flags with fallback files.
    • Example:
      $config = $configResolver->resolveFromInputWithFallback(
          $input, // Symfony\Component\Console\Input\InputInterface
          ['config/fallback.php']
      );
      
  2. Parameter-Based Sets:

    • Resolve configs embedded in parameters > sets within PHP config files:
      $parameterSetsConfigs = $configResolver->resolveFromParameterSetsFromConfigFiles($configs);
      $mergedConfigs = array_merge($configs, $parameterSetsConfigs);
      
  3. Service Provider Integration:

    • Bind the resolver to Laravel’s container for reuse:
      // app/Providers/AppServiceProvider.php
      public function register()
      {
          $this->app->singleton('config.resolver', function () {
              return new SetAwareConfigResolver(new YourSetProvider());
          });
      }
      
  4. Artisan Command Integration:

    • Extend Illuminate\Console\Command and resolve configs in handle():
      use Illuminate\Support\Facades\App;
      
      protected function handle()
      {
          $config = App::make('config.resolver')->resolveFromInputWithFallback(
              $this->input,
              ['config/default.php']
          );
          config($config);
          // Proceed with logic...
      }
      
  5. Config Merging:

    • Manually merge resolved configs into Laravel’s config:
      $resolved = $configResolver->resolve(...);
      config()->set($resolved); // Overwrites existing keys
      // OR
      config()->merge($resolved); // Recursively merges
      

Workflows

  1. Development Workflow:

    • Use --config flags to override local development settings:
      php artisan my:tool --config=config/dev.php
      
    • Store project-specific configs in config/ and commit them to version control.
  2. CI/CD Workflow:

    • Pass configs via environment variables or CLI flags in pipelines:
      php artisan my:tool --config=config/ci.php
      
    • Use resolveFromParameterSetsFromConfigFiles to dynamically include sets based on pipeline stages.
  3. Plugin/System Architecture:

    • For tools with plugins (e.g., ECS/Rector), use SetProviderInterface to register plugin-specific configs:
      class PluginSetProvider implements SetProviderInterface
      {
          public function getSets(): array
          {
              return [
                  'plugin-set' => ['plugin' => ['option' => 'value']],
              ];
          }
      }
      

Integration Tips

  1. Laravel Config Precedence:

    • Ensure resolved configs respect Laravel’s precedence (env > config files > defaults). Override config() behavior if needed:
      config(['my_tool' => array_merge(config('my_tool', []), $resolved)]);
      
  2. Symfony Console Compatibility:

    • Use Symfony\Component\Console\Input\ArgvInput for CLI entry points or Symfony\Component\Console\Input\ArrayInput for testing:
      $input = new ArrayInput(['--config' => 'path/to/config.php']);
      
  3. Testing:

    • Mock SetAwareConfigResolver in PHPUnit tests:
      $mockResolver = $this->createMock(SetAwareConfigResolver::class);
      $mockResolver->method('resolveFromInputWithFallback')
          ->willReturn(['test' => 'value']);
      $this->app->instance('config.resolver', $mockResolver);
      
  4. Performance:

    • Cache resolved configs in Laravel’s cache if configs are static:
      $cacheKey = 'my_tool_config_' . md5(filemtime('config/default.php'));
      $config = Cache::remember($cacheKey, now()->addHours(1), function () use ($configResolver) {
          return $configResolver->resolve(...);
      });
      

Gotchas and Tips

Pitfalls

  1. Config Overwrite vs. Merge:

    • Laravel’s config() overwrites existing keys by default, while Symfony’s ParameterBag may behave differently. Explicitly use config()->merge() for recursive merging:
      // Bad: Overwrites all existing keys
      config($resolved);
      
      // Good: Recursively merges
      config()->merge($resolved);
      
  2. Null Handling:

    • resolveFromInputWithFallback() returns null if no config is found. Always check for null:
      $config = $configResolver->resolve(...);
      if ($config === null) {
          $config = config('defaults.my_tool', []); // Fallback to defaults
      }
      
  3. Symfony DI Container:

    • The package expects a Symfony ParameterBag for config storage. Laravel’s config() uses a different structure. Bridge the gap with an adapter:
      class LaravelConfigAdapter
      {
          public function __construct(private SetAwareConfigResolver $resolver)
          {
          }
      
          public function resolve(array $fallbacks): array
          {
              $symfonyConfig = $this->resolver->resolve(...);
              return is_array($symfonyConfig) ? $symfonyConfig : [];
          }
      }
      
  4. CLI Argument Parsing:

    • The package uses Symfony’s ArgvInput, which may not handle Laravel’s Artisan-specific flags (e.g., --help). Test thoroughly with your CLI tool’s flags.
  5. Archived Package Risk:

    • The package is archived with no active maintenance. Monitor for:
      • Symfony version compatibility issues.
      • Security vulnerabilities in dependencies (e.g., Symfony Console).
    • Consider forking or wrapping the core logic in a Laravel-specific package.
  6. Config File Format:

    • The resolver expects PHP arrays. YAML/JSON configs require manual conversion or a pre-processing step:
      $yamlConfig = yaml_parse_file('config/config.yaml');
      $configResolver->resolve([$yamlConfig]);
      

Debugging

  1. Config Resolution Issues:

    • Enable Symfony’s debug mode to inspect resolved configs:
      $configResolver = new SetAwareConfigResolver($setProvider, true); // Enable debug
      
    • Check for Symplify\SetConfigResolver\Exception\ConfigFileNotFoundException if files are missing.
  2. Precedence Conflicts:

    • Use dd(config()->all()) to inspect the merged config state after resolution. Look for unexpected overwrites.
  3. Set Provider Errors:

    • If resolveFromParameterSetsFromConfigFiles fails, verify:
      • The SetProviderInterface implementation is correct.
      • Config files contain valid parameters > sets arrays:
        return [
            'parameters' => [
                'sets' => ['set1', 'set2'],
            ],
        ];
        

Tips

  1. Custom Set Providers:

    • Extend functionality by creating custom SetProviderInterface implementations:
      class DynamicSetProvider implements SetProviderInterface
      {
          public function getSets(): array
          {
              return [
                  'dynamic-set' => [
                      'value' => env('DYNAMIC_VALUE', 'default'),
                  ],
              ];
          }
      }
      
  2. Environment-Aware Configs:

    • Combine with Laravel’s env()
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
calliostro/spotify-bundle
calmfox/watch-sylius
damienfern/grpc-symfony-bundle
atoolo/index-bundle
atoolo/genai-bundle
coprotoai/laravel-ticket
davidjln/llm-carbon-bundle
cryonighter/valid-request-bundle
coolms/taxonomy-bundle
coolms/field-bundle
articulate-orm/symfony
aaix/laravel-tall-architect
ephoto/akeneo-connector
emmanuelballery/eb-plantumlbundle
emielburgman/symfony-visitor-beacon
emielburgman/symfony-visit-storage
emielburgman/symfony-security-headers
emielburgman/symfony-log-viewer
emarref/xdebug-bundle
emarref/pubnub-bundle