How do I read configuration settings from Symfony2 config.yml?

前端 未结 6 1511
花落未央
花落未央 2020-11-27 09:16

I have added a setting to my config.yml file as such:

app.config:
    contact_email: somebody@gmail.com
    ...

For the life of me, I can\'

相关标签:
6条回答
  • 2020-11-27 09:43

    While the solution of moving the contact_email to parameters.yml is easy, as proposed in other answers, that can easily clutter your parameters file if you deal with many bundles or if you deal with nested blocks of configuration.

    • First, I'll answer strictly the question.
    • Later, I'll give an approach for getting those configs from services without ever passing via a common space as parameters.

    FIRST APPROACH: Separated config block, getting it as a parameter

    With an extension (more on extensions here) you can keep this easily "separated" into different blocks in the config.yml and then inject that as a parameter gettable from the controller.

    Inside your Extension class inside the DependencyInjection directory write this:

    class MyNiceProjectExtension extends Extension
    {
        public function load( array $configs, ContainerBuilder $container )
        {
            // The next 2 lines are pretty common to all Extension templates.
            $configuration = new Configuration();
            $processedConfig = $this->processConfiguration( $configuration, $configs );
    
            // This is the KEY TO YOUR ANSWER
            $container->setParameter( 'my_nice_project.contact_email', $processedConfig[ 'contact_email' ] );
    
            // Other stuff like loading services.yml
        }
    

    Then in your config.yml, config_dev.yml and so you can set

    my_nice_project:
        contact_email: someone@example.com
    

    To be able to process that config.yml inside your MyNiceBundleExtension you'll also need a Configuration class in the same namespace:

    class Configuration implements ConfigurationInterface
    {
        public function getConfigTreeBuilder()
        {
            $treeBuilder = new TreeBuilder();
            $rootNode = $treeBuilder->root( 'my_nice_project' );
    
            $rootNode->children()->scalarNode( 'contact_email' )->end();
    
            return $treeBuilder;
        }
    }
    

    Then you can get the config from your controller, as you desired in your original question, but keeping the parameters.yml clean, and setting it in the config.yml in separated sections:

    $recipient = $this->container->getParameter( 'my_nice_project.contact_email' );
    

    SECOND APPROACH: Separated config block, injecting the config into a service

    For readers looking for something similar but for getting the config from a service, there is even a nicer way that never clutters the "paramaters" common space and does even not need the container to be passed to the service (passing the whole container is practice to avoid).

    This trick above still "injects" into the parameters space your config.

    Nevertheless, after loading your definition of the service, you could add a method-call like for example setConfig() that injects that block only to the service.

    For example, in the Extension class:

    class MyNiceProjectExtension extends Extension
    {
        public function load( array $configs, ContainerBuilder $container )
        {
            $configuration = new Configuration();
            $processedConfig = $this->processConfiguration( $configuration, $configs );
    
            // Do not add a paramater now, just continue reading the services.
            $loader = new YamlFileLoader( $container, new FileLocator( __DIR__ . '/../Resources/config' ) );
            $loader->load( 'services.yml' );
    
            // Once the services definition are read, get your service and add a method call to setConfig()
            $sillyServiceDefintion = $container->getDefinition( 'my.niceproject.sillymanager' );
            $sillyServiceDefintion->addMethodCall( 'setConfig', array( $processedConfig[ 'contact_email' ] ) );
        }
    }
    

    Then in your services.yml you define your service as usual, without any absolute change:

    services:
        my.niceproject.sillymanager:
            class: My\NiceProjectBundle\Model\SillyManager
            arguments: []
    

    And then in your SillyManager class, just add the method:

    class SillyManager
    {
        private $contact_email;
    
        public function setConfig( $newConfigContactEmail )
        {
            $this->contact_email = $newConfigContactEmail;
        }
    }
    

    Note that this also works for arrays instead of scalar values! Imagine that you configure a rabbit queue and need host, user and password:

    my_nice_project:
        amqp:
            host: 192.168.33.55
            user: guest
            password: guest
    

    Of course you need to change your Tree, but then you can do:

    $sillyServiceDefintion->addMethodCall( 'setConfig', array( $processedConfig[ 'amqp' ] ) );
    

    and then in the service do:

    class SillyManager
    {
        private $host;
        private $user;
        private $password;
    
        public function setConfig( $config )
        {
            $this->host = $config[ 'host' ];
            $this->user = $config[ 'user' ];
            $this->password = $config[ 'password' ];
        }
    }
    

    Hope this helps!

    0 讨论(0)
  • 2020-11-27 09:58

    Like it was saying previously - you can access any parameters by using injection container and use its parameter property.

    "Symfony - Working with Container Service Definitions" is a good article about it.

    0 讨论(0)
  • 2020-11-27 10:00

    Rather than defining contact_email within app.config, define it in a parameters entry:

    parameters:
        contact_email: somebody@gmail.com
    

    You should find the call you are making within your controller now works.

    0 讨论(0)
  • 2020-11-27 10:05

    I have to add to the answer of douglas, you can access the global config, but symfony translates some parameters, for example:

    # config.yml
    ... 
    framework:
        session:
            domain: 'localhost'
    ...
    

    are

    $this->container->parameters['session.storage.options']['domain'];
    

    You can use var_dump to search an specified key or value.

    0 讨论(0)
  • 2020-11-27 10:07

    I learnt a easy way from code example of http://tutorial.symblog.co.uk/

    1) notice the ZendeskBlueFormBundle and file location

    # myproject/app/config/config.yml
    
    imports:
        - { resource: parameters.yml }
        - { resource: security.yml }
        - { resource: @ZendeskBlueFormBundle/Resources/config/config.yml }
    
    framework:
    

    2) notice Zendesk_BlueForm.emails.contact_email and file location

    # myproject/src/Zendesk/BlueFormBundle/Resources/config/config.yml
    
    parameters:
        # Zendesk contact email address
        Zendesk_BlueForm.emails.contact_email: dunnleaddress@gmail.com
    

    3) notice how i get it in $client and file location of controller

    # myproject/src/Zendesk/BlueFormBundle/Controller/PageController.php
    
        public function blueFormAction($name, $arg1, $arg2, $arg3, Request $request)
        {
        $client = new ZendeskAPI($this->container->getParameter("Zendesk_BlueForm.emails.contact_email"));
        ...
        }
    
    0 讨论(0)
  • 2020-11-27 10:09

    In order to be able to expose some configuration parameters for your bundle you should consult the documentation for doing so. It's fairly easy to do :)

    Here's the link: How to expose a Semantic Configuration for a Bundle

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