web-dev-qa-db-ja.com

symfony 2でAppKernel環境変数にアクセスする

私はsymfony 2を使用していますが、devとprodの2つの構成があります。エンティティまたはモデル内で使用しているものを見つけることができるかどうかを知る必要があります。

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」のどちらにいるのかを、サービスまたはモデルから簡単に判断できる方法があるかどうかです。ありがとう

26
ContextSwitch

コンソールによって生成されたデフォルトのエンティティクラスは何も継承しません。これは、それらが「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;
}

これはあなたのために働くでしょうか?

PSあなたが投稿したイベントリスナーはコントローラー用です-任意のクラス用ではありません。

51
Peter Bailey

パラメータとして取得することもできます。 _\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');
_

githubのKernel.phpクラスを参照

19

もちろん、グローバルの迅速で汚い方法があります...

function quickAndDirty() {
   global $kernel;

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

悪い面と悪い面があり、使用後は自分で洗う必要がありますが、継承した可能性のある大規模な既存のコードベースの場合、リファクタリングの悪夢を回避できます。

もちろん、そのような方法を使用した後に自分と一緒に暮らすことができるかどうかはあなた次第です;)

1
Steve Childs

(注:これは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
        }
    }
}

これには、単体テストを行う場合、コンテナが必要ないという利点があります。

プロパティの注入が気に入らない場合は、コンストラクターまたはセッターの注入を使用できます。

1
Henry