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

Config Laravel Package

symfony/config

Symfony Config component helps you find, load, merge, autofill, and validate configuration from sources like YAML, XML, INI, or databases. Provides structured handling of config values for reusable, consistent application setups.

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup in Laravel
1. **Installation**:
   ```bash
   composer require symfony/config

Laravel already uses this package under the hood for configuration management (e.g., config/, bootstrap/app.php).

  1. First Use Case: Define a custom configuration structure for a package or service. For example, create a config/my-package.php file:

    return [
        'enabled' => env('MY_PACKAGE_ENABLED', false),
        'timeout' => env('MY_PACKAGE_TIMEOUT', 30),
        'services' => [
            'api' => [
                'url' => env('MY_PACKAGE_API_URL', 'https://api.example.com'),
            ],
        ],
    ];
    
  2. Load Configuration: Use Laravel’s built-in config() helper or access it directly via the Config facade:

    $config = config('my-package.enabled'); // Returns `false` or the env value
    
  3. Validation: Leverage Symfony’s Definition and NodeBuilder to validate config files programmatically:

    use Symfony\Component\Config\Definition\Builder\TreeBuilder;
    use Symfony\Component\Config\Definition\ConfigurationInterface;
    
    class MyPackageConfig implements ConfigurationInterface
    {
        public function getConfigTreeBuilder(): TreeBuilder
        {
            $treeBuilder = new TreeBuilder('my_package');
            $rootNode = $treeBuilder->getRootNode();
    
            $rootNode
                ->children()
                    ->booleanNode('enabled')->defaultFalse()->end()
                    ->integerNode('timeout')
                        ->min(5)
                        ->max(120)
                        ->defaultValue(30)
                    ->end()
                    ->arrayNode('services')
                        ->addDefaultsIfNotSet()
                        ->children()
                            ->arrayNode('api')
                                ->children()
                                    ->scalarNode('url')->cannotBeEmpty()->end()
                                ->end()
                            ->end()
                        ->end()
                    ->end()
                ->end();
    
            return $treeBuilder;
        }
    }
    

    Register this in a service provider’s boot() method:

    $this->app->make('config')->set(MyPackageConfig::class, 'my-package');
    

Implementation Patterns

1. Configuration Validation and Merging

  • Pattern: Use ConfigurationInterface to enforce strict config schemas. Example:
    $config = $this->app['config'];
    $config->shouldValidate(MyPackageConfig::class, 'my-package');
    
  • Workflow:
    1. Define a ConfigurationInterface for your package.
    2. Register it with Laravel’s config system.
    3. Validate user-provided config (e.g., in a service provider or command) by calling shouldValidate().

2. Environment Variable Integration

  • Pattern: Combine Symfony’s config with Laravel’s .env files using placeholders:
    # config/my-package.yaml
    services:
        api:
            url: '%env(MY_PACKAGE_API_URL)%'
    
  • Tip: Use env() helper in PHP config files for dynamic values:
    return [
        'timeout' => env('MY_PACKAGE_TIMEOUT', 30),
    ];
    

3. Dynamic Configuration Loading

  • Pattern: Load config from multiple sources (YAML, PHP, database) and merge them:
    use Symfony\Component\Config\Loader\LoaderInterface;
    use Symfony\Component\Config\Loader\DelegatingLoader;
    
    $loader = new DelegatingLoader([
        new YamlFileLoader($this->app['path.config'].'/my-package'),
        new PhpFileLoader($this->app['path.config']),
    ]);
    $config = $loader->load('my-package');
    
  • Integration Tip: Extend Laravel’s ConfigRepository to support custom loaders.

4. Package Development

  • Pattern: Publish config files for user customization:
    // In a service provider
    $this->publishes([
        __DIR__.'/../config/my-package.php' => config_path('my-package.php'),
    ], 'config');
    
  • Workflow:
    1. Define default config in your package.
    2. Publish it to config/ during installation.
    3. Merge user overrides with defaults using Symfony’s NodeBuilder.

5. Enum and Complex Type Support

  • Pattern: Validate enums or complex types (e.g., arrays of objects):
    use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
    
    $rootNode->children()
        ->enumNode('status')
            ->values(['active', 'inactive', 'pending'])
        ->end()
        ->arrayNode('roles')
            ->prototype('scalar')->end()
        ->end();
    

Gotchas and Tips

Pitfalls

  1. Deprecated Features:

    • Symfony 8+ drops support for the fluent PHP config format (e.g., $this->loadFromExtension()). Use YAML or PHP arrays instead.
    • Avoid mixing defaultValue() and isRequired() in NodeBuilder (throws InvalidArgumentException).
  2. Case Sensitivity:

    • Config keys are case-sensitive in YAML but not in PHP arrays. Normalize keys (e.g., snake_case) for consistency.
  3. Circular References:

    • Symfony’s config loader may fail with circular references in include statements. Use absolute paths or avoid circular includes.
  4. Environment Placeholders:

    • Placeholders like %env(MY_VAR)% must be resolved before validation. Use ParameterBag or Laravel’s env() helper to pre-process values.
  5. Array Merging Quirks:

    • Deep merging (e.g., nested arrays) may drop keys if not explicitly configured. Use ->ignoreExtraKeys(false) or ->normalizeKeys(false) in ArrayNodeDefinition.

Debugging Tips

  1. Enable Debug Mode: Symfony’s DefinitionErrorException provides detailed validation errors. Enable Laravel’s debug mode (APP_DEBUG=true) for stack traces.

  2. Inspect Config Tree: Dump the config tree to debug structure:

    $configTree = (new MyPackageConfig())->getConfigTreeBuilder()->buildTree();
    var_dump($configTree->getRootNode()->getSchema());
    
  3. Validate Without Throwing: Use validate() with a ValidationExceptionHandler to catch errors gracefully:

    try {
        $config->validate(MyPackageConfig::class, 'my-package');
    } catch (\Symfony\Component\Config\Definition\Exception\InvalidConfigurationException $e) {
        report($e);
    }
    

Extension Points

  1. Custom Resource Loaders: Extend FileLocator or LoaderInterface to load config from databases, APIs, or S3:

    class ApiConfigLoader implements LoaderInterface
    {
        public function load($resource, $type = null)
        {
            $data = $this->fetchFromApi($resource);
            return $data;
        }
        public function supports($resource, $type = null) { /* ... */ }
    }
    
  2. Dynamic Node Factories: Create reusable NodeDefinition factories for common patterns (e.g., API endpoints):

    class ApiEndpointNodeDefinition extends ArrayNodeDefinition
    {
        public function __construct(string $name)
        {
            $this->addDefaultsIfNotSet()
                ->children()
                    ->scalarNode('url')->isRequired()->end()
                    ->integerNode('timeout')->defaultValue(30)->end()
                ->end();
        }
    }
    
  3. Override Default Config: Use Laravel’s mergeConfigFrom to override package defaults:

    $this->mergeConfigFrom(__DIR__.'/config/my-package.php', 'my-package');
    

Performance Tips

  1. Cache Config Validation: Cache the compiled config tree to avoid re-parsing on every request:

    $cache = new \Symfony\Component\Cache\Simple\FilesystemCache(sys_get_temp_dir());
    $configTree = $cache->get('my_package_config_tree', function() {
        return (new MyPackageConfig())->getConfigTreeBuilder()->buildTree();
    });
    
  2. Lazy-Load Config: Load config only when needed (e.g., in a service provider’s register()):

    $this->app->singleton('my-package.config', function() {
        return $this->app['config']->get('my-package');
    });
    
  3. Avoid Redundant Merging: Use ->beforeNormalization() or ->beforeValidation() in NodeBuilder to pre-process values and reduce merging overhead.


```markdown
### **Laravel-Specific Quirks**
1. **Service Container Integration**:
   Bind config validators to the container for reuse:
   ```php
   $this->app->bind(MyPackageConfig::class, function() {
       return new MyPackageConfig();
   });
  1. Artisan Commands: Validate config in commands using Laravel’s validate() helper:
    use Symfony
    
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.
codraw/framework-extra-bundle
codraw/messenger
codraw/security
codraw/mailer
codraw/contracts
codraw/profiling
codraw/dependency-injection
codraw/tester
codraw/core
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony