Подтвердить что ты не робот

Доступ к переменной среды AppKernel в symfony 2

Я использую symfony 2, и у нас есть 2 конфигурации, dev и prod. Мне нужно знать, могу ли я узнать, какой из них использовать внутри объекта или модели.

Я ищу что-то похожее на этот код, найденный в AppKernel.php:

$this->getEnvironment()

Если бы я мог загрузить Ядро, чтобы назвать это, это было бы здорово, но я не могу найти способ сделать это. Изучив это, выяснилось, что события symfony могут возвращать Ядро, но я не знаю, как и где можно захватить эти события, чтобы я мог называть getKernel() на них. http://symfony.com/doc/current/book/internals.html

Например, они перечисляют этот пример:

использовать 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);
}

Непонятно мне, где поставить этот блок кода. Мне кажется, что он должен идти в ядре, и если бы у меня было Ядро, у меня не было бы этой проблемы.

Мой вопрос в том, есть ли простой способ для меня определить, находится ли я в 'dev' или 'prod', как установлено в ядре, из Сервиса или Модели. Благодаря

4b9b3361

Ответ 1

Класс сущности по умолчанию, сгенерированный консолью, не наследует ничего. Это означает, что они не являются "ContainerAware".

И вообще, я не думаю, что они должны быть. Я полагал, что это зависит от того, что вы делаете, но вы можете справиться с этим с помощью базовой инъекции зависимостей

В контроллере:

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

И затем в src/Your/Bundle/Entity/Foo.php

private $env;

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

Будет ли это работать для вас?

P.S. Слушатель событий, о котором вы писали, предназначен для контроллеров - не для произвольных классов.

Ответ 2

Это также можно получить как параметр. Если вы посмотрите на класс \Symfony\Component\HttpKernel\Kernel, вы найдете метод getKernelParameters(), который предоставляет все параметры ядра.

/**
 * 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()
    );
}

Итак, в файле services.yml вы можете получить среду с %kernel.environment%, в то время как в классе, поддерживающем контейнер, вы можете получить ее, выполнив:

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

см. класс Kernel.php на github

Ответ 3

Конечно, есть быстрый и грязный способ глобализации...

function quickAndDirty() {
   global $kernel;

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

Его плохое и злое, и вы должны помыться после его использования, но в случае большой существующей кодовой базы, которую вы, возможно, унаследовали, она сохраняет потенциальный кошмар рефакторинга.

Конечно, независимо от того, можете ли вы жить с самим собой после использования такого метода, зависит от вас;)

Ответ 4

(Примечание: это работает на Symfony 3.x, не уверен насчет 4.x)

Вы можете %kernel.environment% прямо в ваш сервис:

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

Тогда в вашем классе обслуживания:


class Foo {

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

Это имеет то преимущество, что если вы проводите модульное тестирование, вам не нужен контейнер.

Если вам не нравится внедрение свойств, вы можете использовать конструктор или метод установки.