2014-04-18 9 views
8

Próbuję dynamicznie ustawić parametr w Symfony2 (którego nie mogę ustawić statycznie w moim pliku parameters.yml). Moje podejście jest użyć EventListener:Jak mogę dynamicznie ustawić parametr w Symfony2?

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); 
    } 
} 

A moja definicja usługi w config.yml wygląda następująco:

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

Problem jest, otrzymuję wyjątek:

LogicException: Impossible wywołanie metody set() dla zamrożonej ParameterBag.

Jak mogę obejść ten wyjątek lub czy widzisz inny sposób dynamicznego ustawiania parametru?

Odpowiedz

8

Reguła parametry kontenerów jest to, że:

można tylko ustawić parametr przed pojemnik jest kompilowany

Jak rozwiązać problem zależy od potrzeb przy założeniu, że pojemnik jest nie uważano, że ma parametry dynamiczne.

  1. tworzyć niestandardowe Ci dynamiczne „Opcje” usługę i wstrzyknąć go w innych usługach, w ten sposób można również zarządzać parametrów w bazie danych (takich jak wordpress wp_options), ale nie wiem jak to zrobić, że pakiet . W przypadku istniejących usług (np. Mailer) you can use configurators.

  2. unieważnić pamięć podręczną, gdy parametry ulegną zmianie here an easy method, więc po przeładowaniu strony pojemnik zostanie odbudowany. Jeśli parametry zmieniają się często, często ryzykuje się ponowne załadowanie pamięci podręcznej i staje się to problemem, jeśli masz duże obciążenia.

jeśli wybierzesz drugą opcję należy ustawić parametry zanim zostanie wypełniony w pojemniku, dzięki czemu można:

  • eksportu w niestandardowy plik YAML załadowanego app/config/config .yml, gdy parametry zmieniają się przed wyczyszczeniem pamięci podręcznej, w ten sposób można uzyskać dane z innych usług
  • parametry ładowania w rozszerzeniu pakietu here the cookbook, w ten sposób nie można uzyskać dostępu do innych usług, aby uzyskać dane, rozszerzenie może uzyskać dostęp tylko do producenta kontenerów

Proponuję jednak opcję 1 (opcje usługi i konfiguratory), ponieważ (powtarzam) kontener nie ma parametrów dynamicznych, ale oferuje możliwość posiadania niestandardowych konfiguratorów usług dynamicznych, które wykorzystują dane z dowolnego źródła.

1

Wystąpił problem z listą adresów URL rozpoczynających się od %base_url%, kiedy chciałem zrobić system awaryjny.

W końcu zastąpiłem %base_url% przez #base_url# i wykonałem ręczną procedurę zastępczą w usłudze.

$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 
} 
0

Myślę, że możemy dodać parametry do prostych funkcji klasowych do usługi.

To jest moja funkcja kontrolera.

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

To jest mój serwis

<?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; 
    } 
} 
Powiązane problemy