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, auto-fill, and validate configuration from many sources (YAML, XML, INI, databases, etc.). Provides tools for building robust, consistent configuration handling in PHP apps and libraries.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require symfony/config
    

    Add to composer.json if using standalone:

    "require": {
        "symfony/config": "^8.0"
    }
    
  2. First Use Case: Define a configuration tree for a Laravel package or app module. Example:

    use Symfony\Component\Config\Definition\Builder\TreeBuilder;
    use Symfony\Component\Config\Definition\ConfigurationInterface;
    
    class AppConfig implements ConfigurationInterface
    {
        public function getConfigTreeBuilder(): TreeBuilder
        {
            $treeBuilder = new TreeBuilder('app');
            $rootNode = $treeBuilder->getRootNode();
    
            $rootNode
                ->children()
                    ->scalarNode('name')
                        ->isRequired()
                        ->cannotBeEmpty()
                    ->end()
                    ->arrayNode('features')
                        ->useAttributeAsKey('name')
                        ->prototype('array')
                            ->children()
                                ->booleanNode('enabled')->defaultTrue()->end()
                            ->end()
                        ->end()
                    ->end()
                ->end();
    
            return $treeBuilder;
        }
    }
    
  3. Loading Configuration:

    use Symfony\Component\Config\FileLocator;
    use Symfony\Component\Config\Loader\LoaderResolver;
    use Symfony\Component\Config\Loader\DelegatingLoader;
    use Symfony\Component\Config\Loader\YamlFileLoader;
    
    $locator = new FileLocator(__DIR__.'/config');
    $resolver = new LoaderResolver([
        new YamlFileLoader($locator, 'yaml'),
    ]);
    $loader = new DelegatingLoader($resolver);
    
    $config = $loader->load('app.yaml');
    

Where to Look First

  • Official Documentation for core concepts.
  • TreeBuilder and ConfigurationInterface for defining schemas.
  • Loader classes (YamlFileLoader, XmlFileLoader, etc.) for parsing files.
  • Definition nodes (scalarNode, arrayNode, booleanNode) for structuring config.

Implementation Patterns

1. Defining Configuration Schemas

Use TreeBuilder to define hierarchical config structures with validation rules. Example: Laravel Package Config

$treeBuilder = new TreeBuilder('my_package');
$rootNode = $treeBuilder->getRootNode();

$rootNode
    ->children()
        ->arrayNode('database')
            ->addDefaultsIfNotSet()
            ->children()
                ->scalarNode('connection')->defaultValue('mysql')->end()
                ->scalarNode('host')->defaultValue('%env(DATABASE_HOST)%')->end()
                ->integerNode('port')->min(1024)->max(65535)->defaultValue(3306)->end()
            ->end()
        ->end()
        ->arrayNode('cache')
            ->prototype('scalar')->end()
        ->end()
    ->end();

2. Loading Configuration from Multiple Sources

Combine YAML, XML, PHP arrays, or environment variables:

$loader = new DelegatingLoader([
    new YamlFileLoader($locator, 'yaml'),
    new XmlFileLoader($locator, 'xml'),
    new PhpFileLoader($locator, 'php'),
]);

$config = $loader->load([
    'yaml' => 'config/packages.yaml',
    'env'  => ['DATABASE_URL' => getenv('DATABASE_URL')],
]);

3. Environment Variable Integration

Use ParameterBag or Dotenv to merge env vars into config:

use Symfony\Component\Dotenv\Dotenv;

$dotenv = new Dotenv();
$dotenv->load(__DIR__.'/../.env');

$configurator = new \Symfony\Component\Config\Definition\Configurator\DefinitionConfigurator();
$configurator->rootNode()
    ->children()
        ->scalarNode('api_key')
            ->defaultValue('%env(API_KEY)%')
        ->end()
    ->end();

4. Validation and Normalization

Leverage built-in validators for types, ranges, and patterns:

$rootNode
    ->scalarNode('timeout')
        ->validate()
            ->ifTrue(function ($value) { return $value < 1; })
            ->thenInvalid('Timeout must be at least 1 second.')
        ->end()
    ->end();

5. Dynamic Configuration with Callbacks

Use beforeNormalization/afterNormalization for runtime logic:

$rootNode->beforeNormalization()->ifTrue(function ($v) {
    return isset($v['features']['debug']) && $v['features']['debug'];
})->then(function ($v) {
    $v['features']['debug']['enabled'] = true;
    return $v;
});

6. Laravel-Specific Workflow

Integrate with Laravel’s config() helper:

// In a Service Provider
public function boot()
{
    $config = (new AppConfig())->getConfigTreeBuilder()->buildTree();
    $config->setRootNode(new \Symfony\Component\Config\Definition\Node(
        $config->getRootNode()->normalize($this->app['config']->all())
    ));
    $this->app->singleton('my_package.config', function () use ($config) {
        return $config->getRootNode()->getValue();
    });
}

Gotchas and Tips

Common Pitfalls

  1. Circular References: Avoid recursive config definitions (e.g., nested arrayNode with same key). Fix: Use ->ignoreExtraKeys() or flatten structures.

  2. Case Sensitivity: YAML keys are case-sensitive. Use ->normalizeKey(function ($key) { return strtolower($key); }) if needed.

  3. Default Values vs. Required Fields: A node cannot have both isRequired() and defaultValue(). Choose one.

  4. Environment Placeholders: Use %env(KEY)% syntax, but ensure the env var exists or provide a fallback:

    ->defaultValue('%env(APP_DEBUG)%')->defaultFalse()
    
  5. ArrayNode Prototype Issues: If using ->prototype(), ensure keys are unique (e.g., with useAttributeAsKey('name')).

  6. Deprecated Features (Symfony 8+):

    • Fluent PHP config format is removed (use YAML/XML/arrays).
    • getXsdValidationBasePath() and getNamespace() in ExtensionInterface are deprecated.

Debugging Tips

  1. Dump Raw Config:

    $config = $loader->load('config.yaml');
    dump($config->getRootNode()->getValue());
    
  2. Validate Schema: Use ->validate() with custom callbacks to catch issues early:

    $rootNode->validate()
        ->ifTrue(function ($v) { return empty($v['database']['host']); })
        ->thenInvalid('Database host is required.');
    
  3. Check for Unreachable Paths: Symfony 7.3+ auto-detects unreachable config paths. Enable strict mode:

    $treeBuilder->setStrictMode(true);
    
  4. Environment-Specific Configs: Use LoaderResolver to load environment-specific files:

    $resolver = new LoaderResolver([
        new YamlFileLoader($locator, 'yaml'),
    ]);
    $loader = new DelegatingLoader($resolver, 'app.'.app()->environment().'.yaml');
    

Extension Points

  1. Custom Loaders: Extend FileLoader for proprietary formats (e.g., JSON5, TOML):

    class Json5FileLoader extends FileLoader
    {
        protected function load($resource, $type = null)
        {
            return json_decode(file_get_contents($resource), true, 512, JSON5_THROW_ON_ERROR);
        }
    }
    
  2. Dynamic Node Factories: Use NodeFactory to create nodes programmatically:

    $factory = new NodeFactory();
    $node = $factory->createNode(
        new ArrayNode('dynamic'),
        ['key' => 'value']
    );
    
  3. Post-Processing: Attach listeners to modify config after loading:

    $configurator = new DefinitionConfigurator();
    $configurator->rootNode()
        ->afterNormalization()
        ->then(function ($v) {
            $v['processed_at'] = now()->toDateTimeString();
            return $v;
        });
    
  4. Laravel Service Provider Integration: Cache compiled config to avoid reprocessing:

    $this->app->singing('config.cache', function () {
        return Cache::remember('config.my_package', now()->addHours(1), function () {
            return $configurator->getRootNode()->getValue();
        });
    });
    

Performance Optimizations

  1. Compile Config Schemas: Generate PHP classes from TreeBuilder at build time (e.g., using symfony/flex recipes).

  2. Memoize Loaders: Cache loaded

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.
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai