web-dev-qa-db-ja.com

Symfony2でパラメータを動的に設定するにはどうすればよいですか?

Symfony2でパラメータを動的に設定しようとしています(parameters.ymlファイルで静的に設定することはできません)。私のアプローチは、EventListenerを使用することです。

namespace Acme\AcmeBundle\EventListener;

use Symfony\Component\DependencyInjection\Container;

class AcmeListener
{
    private $container;

    public function __construct(Container $container)
    {
        $this->container = $container;
    }

    public function onKernelRequest()
    {
        // Dynamically fetch $bar
        $bar = fetch('foobar');

        // Set parameter
        $this->container->setParameter('foo', $bar);
    }
}

そして、config.ymlの私のサービス定義は次のようになります。

service:
    kernel.listener.acme_listener:
        class: Acme\AcmeBundle\EventListener\AcmeListener
        tags:
            - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
        arguments: [ '@service_container' ]

問題は、例外が発生することです。

LogicException:フリーズしたParameterBagでset()を呼び出すことができません。

この例外を回避するにはどうすればよいですか、またはパラメータを動的に設定する別の方法がありますか?

12

コンテナパラメータのルールは次のとおりです。

コンテナをコンパイルする前にのみパラメータを設定できます

問題を解決する方法は、コンテナに動的パラメータがあるとは考えられていないという前提で、ニーズによって異なります。

  1. カスタムの動的な「オプション」サービスを作成し、それを他のサービスに挿入します。このようにして、データベース内のパラメーターを管理することもできます(wordpress wp_optionsなど)が、そのバンドルはわかりません。これを行います。既存のサービス(例:メーラー)の場​​合 コンフィギュレーターを使用できます

  2. パラメータが変更されたときにキャッシュを無効にする ここでは簡単な方法 したがって、ページをリロードすると、コンテナが再構築されます。パラメータが頻繁に変更されると、キャッシュが頻繁にリロードされるリスクがあり、負荷が大きい場合に問題になります。

2番目のオプションを選択した場合は、コンテナに入力する前にパラメータを設定する必要があるため、次のことができます。

  • キャッシュをクリアする前にパラメーターが変更されたときにapp/config/config.ymlにロードされたカスタムyamlファイルにエクスポートします。これにより、他のサービスからデータを取得できます。
  • バンドル拡張機能でパラメーターをロード ここではクックブック このように、データを取得するために他のサービスにアクセスすることはできず、拡張機能はコンテナービルダーにのみアクセスできます

ただし、オプション1(オプションサービスとコンフィギュレーター)をお勧めします。これは、コンテナーが動的パラメーターを持っているとは考えられていないためですが、任意のソースからのデータを使用するカスタム動的サービスコンフィギュレーターを使用できるためです。

10

フェイルオーバーシステムを実行したいときに、%base_url%で始まるURLのリストに問題がありました。

最終的に%base_url%#base_url#に置き換え、サービスで手動のプレースホルダー解決を行いました。

$tries = array (
        $this->container->getParameter('base_url'),
        $this->container->getParameter('base_url_failover'),
);

foreach ($tries as $try)
{
    $url = str_replace('#base_url#', $try, $unresolvedUrl);

    // whatever
}
1
Alain Tiemblo

パラメータを単純なクラス関数としてサービスに追加できると思います。

これが私のコントローラー機能です。

   /**
     * @Route("/products/checkService")
     * @Template()
     */
    public function checkServiceAction() {            
        $Paypal = $this->get('Paypal');
        return new Response($Paypal->chkVal('dsdd'));
    }

これは私のサービスです

<?php

namespace Eagle\ShopBundle\Services;

use Symfony\Component\HttpFoundation\Response;

class Paypal {      
    public function __construct($var) {
        $this->paypalCongig = $var;
    }

    public function getVal() {
        return $this->paypalCongig;
   }

    public function chkVal($var) {
        return $var;
   }
}
0
vimuth