Creating configurations in Symfony

前端 未结 3 1605
别跟我提以往
别跟我提以往 2020-12-30 15:25

For a few hours now I\'ve been struggling to do the most simple thing you can imagine and it just won\'t work. I\'ve read tons of stackoverflow questions, read the complete

相关标签:
3条回答
  • 2020-12-30 15:45

    you're almost done, you just need to configure your Bundle to use your config parameters, take a look at this answer.

    0 讨论(0)
  • 2020-12-30 15:58

    A few notices:

    In config.yml, you are trying to define import as array. It seems like symfony doesn't allow creating array elements in the root of your config, meaning that you have to nest arrays deeper down the tree. So you can not do:

    company_happy:
        import:
            path: /tmp
        another_import:
            ...
    

    I am not sure this is exactly what you were trying to do, but you defined import as array, which makes me assume so.

    On the other hand, you can do:

    company_happy:
        imports:
            import:
                path: /tmp
            another_import:
                ...
    

    Regarding no extension able to load the configuration error: Make sure your extension file is following naming convetions.It should be called CompanyHappyExtension.php with CompanyHappyExtension class defined inside.

    I have created a sample CompanyHappyBundle bundle which is working fine on Symofny 3 (probably works on S2 as well). Feel free to clone/download it :)

    The services.yml file is an added bonus, as you will most likely need it anyway.

    src/Company/Bundle/HappyBundle/CompanyHappyBundle.php:

    <?php
    
    namespace Company\Bundle\HappyBundle;
    
    use Symfony\Component\HttpKernel\Bundle\Bundle;
    
    class CompanyHappyBundle extends Bundle
    {
    
    }
    

    src/Company/Bundle/HappyBundle/DependencyInjection/CompanyHappyExtension.php

    <?php
    
    namespace Company\Bundle\HappyBundle\DependencyInjection;
    
    use Symfony\Component\DependencyInjection\ContainerBuilder;
    use Symfony\Component\Config\FileLocator;
    use Symfony\Component\HttpKernel\DependencyInjection\Extension;
    use Symfony\Component\DependencyInjection\Loader;
    use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
    
    
    class CompanyHappyExtension extends Extension implements ExtensionInterface
    {
    
    
        public function load(array $configs, ContainerBuilder $container)
        {
            $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
            $loader->load('services.yml');
    
            $configuration = new Configuration();
            $options = $this->processConfiguration($configuration, $configs);
    
            // Do something with your options here
        }
    
    
    }
    

    src/Company/Bundle/HappyBundle/DependencyInjection/Configuration.php

    <?
    
    namespace Company\Bundle\HappyBundle\DependencyInjection;
    
    use Symfony\Component\Config\Definition\Builder\TreeBuilder;
    use Symfony\Component\Config\Definition\ConfigurationInterface;
    
    class Configuration implements ConfigurationInterface
    {
        public function getConfigTreeBuilder()
        {
            $treeBuilder = new TreeBuilder();
            $rootNode = $treeBuilder->root('company_happy');
    
            $rootNode
                ->children()
                    ->arrayNode('imports')
                        ->prototype('array')
                        ->children()
                            ->scalarNode('path')->defaultValue('/tmp')->end()
                            ->scalarNode('method')->defaultValue('ALL')->end()
                            ->booleanNode('move_mail')->defaultValue(true)->end()
                            ->booleanNode('mark_read')->defaultValue(true)->end()
                        ->end()
                    ->end()
                ->end()
            ;
    
            return $treeBuilder;
        }
    }
    

    src/Company/Bundle/HappyBundle/Resources/config/config.yml

    company_happy:
        imports:
            import:
                path: /tmp
    

    src/Company/Bundle/HappyBundle/Resources/config/services.yml

    # Define your services here
    services:
    
    0 讨论(0)
  • 2020-12-30 16:03

    I have solved my own issue but not without trouble. I'm not at all pleased with Symfony's configuration system.

    Step one - Create your config file

    Create a file named config.yml in src/<bundle name>/Resources/config/

    yourbundle:
        param_one: value_one
        param_two: value_two
        param_three: value_three
        param_four: value_four
        param_five:
            subparam_one: subvalue_one
            subparam_two: subvalue_two
            subparam_three: subvalue_three
            subparam_four: subvalue_four
    

    Step two - Importing your configuration file

    Go to app/config/config.yml and add:

    #app/config/config.yml
    imports:
        - { resource: "@YourBundle/Resources/config/config.yml" }
    

    Step three - Create a configuration class

    Create a file named Configuration.php in src/<bundle name>/DependencyInjection/

    namespace YourBundle\DependencyInjection;
    
    use Symfony\Component\Config\Definition\Builder\TreeBuilder;
    use Symfony\Component\Config\Definition\ConfigurationInterface;
    
    class Configuration implements ConfigurationInterface
    {
        /**
         * {@inheritDoc}
         */
        public function getConfigTreeBuilder()
        {
            $treeBuilder = new TreeBuilder();
            $rootNode = $treeBuilder->root('yourbundle');
    
            $rootNode
                ->children()
                    ->scalarNode('param_one')->defaultValue('value_one')->end()
                    ->scalarNode('param_two')->defaultValue('value_two')->end()
                    ->scalarNode('param_three')->defaultValue('value_three')->end()
                    ->scalarNode('param_four')->defaultValue('value_four')->end()
                    ->arrayNode('param_five')
                        ->children()
                            ->scalarNode('subparam_one')->defaultValue('subvalue_one')->end()
                            ->scalarNode('subparam_two')->defaultValue('subvalue_two')->end()
                            ->scalarNode('subparam_three')->defaultValue('subvalue_three')->end()
                            ->scalarNode('subparam_four')->defaultValue('subvalue_four')->end()
                        ->end()
                ->end()
            ;
    
            return $treeBuilder;
        }
    }
    

    Step four - Creating an extension

    Last but not least, you'll have to create an extension. Create a file <yourbundle>Extension.php in src/<your bundle>/DependencyInjection/

    namespace YourBundle\DependencyInjection;
    
    use Symfony\Component\Config\FileLocator;
    use Symfony\Component\DependencyInjection\ContainerBuilder;
    use Symfony\Component\DependencyInjection\Loader;
    use Symfony\Component\HttpKernel\DependencyInjection\Extension;
    
    class YourbundleExtension extends Extension
    {
        /**
         * @var ContainerBuilder
         */
        protected $container;
    
        /**
         * {@inheritDoc}
         */
        public function load(array $configs, ContainerBuilder $container)
        {
            $this->container = $container;
    
            $configuration = new Configuration();
            $config = $this->processConfiguration($configuration, $configs);
    
            foreach ($config as $key => $value) {
                $this->parseNode('yourbundle.'.$key, $value);
            }
    
            $container->setParameter('yourbundle', $config);
        }
    
        /**
         * @param string $name
         * @param mixed  $value
         *
         * @throws \Exception
         */
        protected function parseNode($name, $value)
        {
            if (is_string($value)) {
                $this->set($name, $value);
    
                return;
            }
            if (is_integer($value)) {
                $this->set($name, $value);
    
                return;
            }
            if (is_array($value)) {
                foreach ($value as $newKey => $newValue) {
                    $this->parseNode($name.'.'.$newKey, $newValue);
                }
    
                return;
            }
            if (is_bool($value)) {
                $this->set($name, $value);
    
                return;
            }
            throw new \Exception(gettype($value).' not supported');
        }
    
        /**
         * @param string $key
         * @param mixed  $value
         */
        protected function set($key, $value)
        {
            $this->container->setParameter($key, $value);
        }
    }
    

    All these steps are required just to be able to call a configuration parameter specific for your bundle.

    If any of you know any way to do this easier, feel free to post an answer or comment.

    0 讨论(0)
提交回复
热议问题