web-dev-qa-db-fra.com

Comment lire les paramètres de configuration de Symfony2 config.yml?

J'ai ajouté un paramètre à mon fichier config.yml en tant que tel:

app.config:
    contact_email: [email protected]
    ...

Pour ma vie, je ne peux pas comprendre comment le lire dans une variable. J'ai essayé quelque chose comme ça dans l'un de mes contrôleurs:

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

Mais je reçois une erreur en disant:

Le paramètre "contact_email" doit être défini.

J'ai effacé mon cache, j'ai aussi consulté partout dans la documentation du site rechargé Symfony2, mais je ne peux pas trouver comment faire.

Probablement trop fatigué pour comprendre cela maintenant. Quelqu'un peut-il aider avec ça?

190
josef.van.niekerk

Plutôt que de définir contact_email dans app.config, définissez-le dans une entrée parameters:

parameters:
    contact_email: [email protected]

Vous devriez maintenant trouver l'appel que vous effectuez dans votre contrôleur.

193

Tandis que la solution de déplacer le contact_email vers parameters.yml est simple, comme proposé dans d’autres réponses, cela peut facilement encombrer votre fichier de paramètres si vous traitez avec beaucoup de bundles ou avec des blocs de configuration imbriqués.

  • Tout d'abord, je vais répondre strictement à la question.
  • Plus tard, je donnerai une approche pour obtenir ces configurations à partir de services sans jamais passer par un espace commun en tant que paramètres.

PREMIÈRE APPROCHE: Bloc de configuration séparé, l'obtenir en tant que paramètre

Avec une extension ( plus sur les extensions ici ), vous pouvez facilement la "séparer" en différents blocs dans le config.yml, puis l’injecter en tant que paramètre accessible par le contrôleur.

Dans votre classe d'extension à l'intérieur du répertoire DependencyInjection, écrivez ceci:

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
    }

Ensuite, dans votre config.yml, config_dev.yml et ainsi vous pouvez définir

my_Nice_project:
    contact_email: [email protected]

Pour pouvoir traiter ce config.yml dans votre MyNiceBundleExtension, vous aurez également besoin d'une classe Configuration dans le même espace de noms:

class Configuration implements ConfigurationInterface
{
    public function getConfigTreeBuilder()
    {
        $treeBuilder = new TreeBuilder();
        $rootNode = $treeBuilder->root( 'my_Nice_project' );

        $rootNode->children()->scalarNode( 'contact_email' )->end();

        return $treeBuilder;
    }
}

Vous pouvez ensuite obtenir la configuration de votre contrôleur, comme vous le souhaitez dans votre question initiale, tout en conservant le parameters.yml propre et en le configurant dans le config.yml dans des sections séparées:

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

DEUXIEME APPROCHE: Bloc de configuration séparé, injectant la configuration dans un service

Pour les lecteurs qui recherchent quelque chose de similaire mais qui obtiennent la configuration d’un service, il existe même un moyen plus agréable de ne jamais encombrer l’espace commun des "paramères" et même de ne pas avoir besoin de la container pour être transmise au service conteneur entier est pratique à éviter).

Cette astuce ci-dessus "s'injecte" toujours dans les paramètres de votre config.

Néanmoins, après avoir chargé votre définition du service, vous pouvez ajouter un appel de méthode, comme par exemple setConfig(), qui injecte ce bloc uniquement dans le service.

Par exemple, dans la classe Extension:

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' ] ) );
    }
}

Ensuite, dans votre services.yml, vous définissez votre service comme d'habitude, sans changement absolu:

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

Et ensuite, dans votre classe SillyManager, ajoutez simplement la méthode:

class SillyManager
{
    private $contact_email;

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

Notez que cela fonctionne aussi pour les tableaux plutôt que pour les valeurs scalaires! Imaginez que vous configurez une file d'attente de lapin et que vous ayez besoin de l'hôte, de l'utilisateur et du mot de passe:

my_Nice_project:
    amqp:
        Host: 192.168.33.55
        user: guest
        password: guest

Bien sûr, vous devez changer votre arbre, mais alors vous pouvez faire:

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

puis dans le service faire:

class SillyManager
{
    private $Host;
    private $user;
    private $password;

    public function setConfig( $config )
    {
        $this->Host = $config[ 'Host' ];
        $this->user = $config[ 'user' ];
        $this->password = $config[ 'password' ];
    }
}

J'espère que cela t'aides!

171
Xavi Montero

Je dois ajouter à la réponse de douglas, vous pouvez accéder à la configuration globale, mais symfony traduit certains paramètres, par exemple:

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

sont

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

Vous pouvez utiliser var_dump pour rechercher une clé ou une valeur spécifiée.

34
Felipe Buccioni

Pour pouvoir exposer certains paramètres de configuration de votre bundle, vous devez consulter la documentation correspondante. C'est assez facile à faire :)

Voici le lien: Comment exposer une configuration sémantique pour un paquet

17
Nikola Petkanski

Comme précédemment, vous pouvez accéder à n’importe quel paramètre en utilisant le conteneur d’injection et sa propriété de paramètre.

"Symfony - Utilisation des définitions de service de conteneur" est un bon article à ce sujet.

J'ai appris un moyen facile de l'exemple de code de http://tutorial.symblog.co.uk/

1) notez le ZendeskBlueFormBundle et l'emplacement du fichier

# myproject/app/config/config.yml

imports:
    - { resource: parameters.yml }
    - { resource: security.yml }
    - { resource: @ZendeskBlueFormBundle/Resources/config/config.yml }

framework:

2) notifiez Zendesk_BlueForm.emails.contact_email et l'emplacement du fichier

# myproject/src/Zendesk/BlueFormBundle/Resources/config/config.yml

parameters:
    # Zendesk contact email address
    Zendesk_BlueForm.emails.contact_email: [email protected]

3) remarquez comment je l'obtiens dans $ client et l'emplacement du contrôleur

# 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"));
    ...
    }
3
Dung