web-dev-qa-db-fra.com

Accès à la variable d'environnement AppKernel dans symfony 2

J'utilise symfony 2 et nous avons 2 configurations, dev et prod. J'ai besoin de savoir si je peux savoir lequel utiliser à l'intérieur d'une entité ou d'un modèle.

Je cherche quelque chose de similaire à ce code trouvé dans AppKernel.php:

$this->getEnvironment()

Si je pouvais charger le noyau pour appeler cela, ce serait bien mais je ne trouve pas de moyen de le faire. Après avoir examiné cela, il apparaît que les événements symfony peuvent retourner le noyau mais je ne sais pas comment ni où capturer ces événements afin que je puisse appeler getKernel () sur eux. http://symfony.com/doc/current/book/internals.html

Par exemple, ils répertorient cet exemple:

utiliser Symfony\Component\HttpKernel\Event\FilterControllerEvent;

public function onKernelController(FilterControllerEvent $event)
{
    $controller = $event->getController();
    // ...

    // the controller can be changed to any PHP callable
    $event->setController($controller);
}

Ce n'est pas clair pour moi où mettre ce bloc de code. Il me semble que cela devrait aller dans le noyau, et si j'avais le noyau, je n'aurais pas ce problème.

Ma question est, existe-t-il un moyen facile pour moi de déterminer si je suis en "dev" ou "prod" tel que défini dans le noyau, à partir d'un service ou d'un modèle. Merci

26
ContextSwitch

Les classes d'entités par défaut générées par la console n'héritent de rien. Cela signifie qu'ils ne sont en aucun cas "ContainerAware".

Et d'une manière générale, je ne pense pas qu'ils devraient l'être. Je suppose que cela dépend de ce que vous faites, mais vous pouvez gérer cela avec une injection de dépendance de base

Dans un contrôleur:

$entity = new \Your\Bundle\Entity\Foo(
  $this->container->get( 'kernel' )->getEnvironment()
);

Et puis dans src/Your/Bundle/Entity/Foo.php

private $env;

public function __construct( $env=null )
{
  $this->env = $env;
}

Est-ce que cela fonctionnerait pour vous?

P.S. L'écouteur d'événements que vous avez publié concerne les contrôleurs - pas les classes arbitraires.

51
Peter Bailey

Il est également possible de l'obtenir en tant que paramètre. Si vous jetez un œil à la classe \Symfony\Component\HttpKernel\Kernel, Vous trouverez une méthode getKernelParameters() qui expose tous les paramètres du noyau.

/**
 * Returns the kernel parameters.
 *
 * @return array An array of kernel parameters
 */
protected function getKernelParameters()
{
    $bundles = array();
    foreach ($this->bundles as $name => $bundle) {
        $bundles[$name] = get_class($bundle);
    }

    return array_merge(
        array(
            'kernel.root_dir' => realpath($this->rootDir) ?: $this->rootDir,
            'kernel.environment' => $this->environment,
            'kernel.debug' => $this->debug,
            'kernel.name' => $this->name,
            'kernel.cache_dir' => realpath($this->getCacheDir()) ?: $this->getCacheDir(),
            'kernel.logs_dir' => realpath($this->getLogDir()) ?: $this->getLogDir(),
            'kernel.bundles' => $bundles,
            'kernel.charset' => $this->getCharset(),
            'kernel.container_class' => $this->getContainerClass(),
        ),
        $this->getEnvParameters()
    );
}

Ainsi, dans un fichier services.yml, Vous pouvez obtenir l'environnement avec %kernel.environment% Tandis que dans une classe compatible avec les conteneurs, vous pouvez l'obtenir en faisant:

$this->getContainer()->getParameter('kernel.environment');

voir la classe Kernel.php sur github

19
Francesco Casula

Bien sûr, il y a la voie rapide et sale des mondiaux ...

function quickAndDirty() {
   global $kernel;

   if ($kernel->getEnvironment() == 'dev') {
      // we're in dev mode
   }
}

C'est mauvais et mauvais et vous devez vous laver après l'avoir utilisé, mais dans le cas d'une grande base de code existante dont vous avez peut-être hérité, cela évite un cauchemar potentiel de refactoring.

Bien sûr, c'est à vous de décider si vous pouvez vivre avec vous-même après avoir utilisé une telle méthode;)

1
Steve Childs

(Remarque: cela fonctionne sur Symfony 3.x, pas sûr de 4.x)

Vous pouvez injecter %kernel.environment% directement dans votre service:

    my_service:
        class: My\Foo
        properties:
            env: '%kernel.environment%'

Puis dans votre classe de service:


class Foo {

    $env;
    ...
    function someFunction()
    {
        if($this->env === 'dev') {
            // do some dev stuff
        }
        else {
            // do some prod stuff
        }
    }
}

Cela a l'avantage que si vous effectuez des tests unitaires, vous n'avez pas besoin du conteneur.

Si vous n'aimez pas l'injection de propriété, vous pouvez utiliser l'injection par constructeur ou par définition.

1
Henry