【问题标题】:Accessing the AppKernel environment variable in symfony 2在 symfony 2 中访问 AppKernel 环境变量
【发布时间】:2012-05-25 08:00:24
【问题描述】:

我正在使用 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);
}

我不清楚将这段代码放在哪里。在我看来,它应该放在内核中,如果我有内核,我就不会遇到这个问题。

我的问题是,有没有一种简单的方法可以让我从服务或模型中确定我是在内核中设置的“开发”还是“产品”。 谢谢

【问题讨论】:

    标签: php symfony configuration


    【解决方案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;
    }
    

    这对你有用吗?

    附注您发布的事件侦听器适用于控制器 - 不适用于任意类。

    【讨论】:

    • 我正在使用 Symfony 2.6,我必须这样做:$kernel = $this->container->get('kernel');
    【解决方案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');
    

    see Kernel.php class on github

    【讨论】:

    • 我建议调用 parent::getKernelParameters() 方法以确保在 symfony 的下一版本中添加任何参数时不会忘记任何参数:) return array_merge(parent::getKernelParameters(), array(...));
    【解决方案3】:

    当然有全局变量的快速而肮脏的方式......

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

    它既坏又邪恶,你应该在使用后清洗自己,但如果你可能继承了一个庞大的现有代码库,它可以避免潜在的重构噩梦。

    当然,用了这样的方法后能不能活得好好的,就看你自己了;)

    【讨论】:

    • 请不要这样做
    • @Dan:这种对全局变量的特殊使用有什么问题?如果不在容器感知类中,则仍然完全有必要知道该站点是否在生产中运行。 (在PHP global or $GLOBALS,他们建议使用$GLOBALS['kernel'] 来避免这里的代码可以创建的范围模糊。)
    • 好吧,回答我自己的问题,事实证明,第一个问题是生产中的$GLOBALS['kernel'] 是 Symfony 3.4.22 上的 AppCache 的一个实例,所以这与@987654325 一起崩溃@.
    【解决方案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
            }
        }
    }
    

    这样做的好处是,如果您进行单元测试,则不需要容器。

    如果你不喜欢属性注入,可以使用构造函数或setter注入。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-26
      • 2011-04-26
      相关资源
      最近更新 更多