Pregunta ¿Cómo puedo establecer dinámicamente un parámetro en Symfony2?


Intento establecer dinámicamente un parámetro en Symfony2 (que no puedo establecer estáticamente en mi parameters.yml archivo). Mi enfoque es usar un 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);
    }
}

Y mi definición de servicio en config.yml Se ve como esto:

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

El problema es que recibo una excepción:

LogicException: Imposible llamar a set () en un ParameterBag congelado.

¿Cómo puedo evitar esta excepción o ves otra forma de establecer dinámicamente un parámetro?


10
2018-04-18 15:09


origen


Respuestas:


La regla de parámetros del contenedor es que:

Solo puede establecer un parámetro antes de compilar el contenedor

Cómo solucionar el problema depende de sus necesidades con la premisa de que no se cree que el contenedor tenga parámetros dinámicos.

  1. cree un servicio personalizado de "opciones" dinámicas e inyéctelo en otros servicios, de esta manera también puede administrar sus parámetros en la base de datos (como wordpress wp_options), pero no conozco un paquete que haga esto. Para los servicios existentes (por ejemplo, anuncio publicitario) puedes usar configuradores.

  2. invalidar la caché cuando los cambios de parámetros aquí un método fácil entonces cuando recarga la página, el contenedor se reconstruye. Si los parámetros cambian frecuentemente, existe el riesgo de volver a cargar la memoria caché con frecuencia y esto se convierte en un problema si tiene grandes cargas.

si eliges la segunda opción, debes establecer los parámetros antes de que se llenen en el contenedor, para que puedas:

  • Exporte en un archivo personalizado yaml cargado en la aplicación / config / config.yml cuando los parámetros cambien antes de borrar la caché, de esta manera puede obtener los datos de otros servicios
  • cargar parámetros en una extensión de paquete aquí el libro de cocina, de esta manera no puede acceder a otros servicios para obtener los datos, la extensión puede acceder solo al contenedor

Sugiero, sin embargo, la opción 1 (servicio de opciones y configuradores) porque (repito) no se cree que el contenedor tenga parámetros dinámicos, pero ofrece la posibilidad de tener configuradores de servicio dinámicos personalizados que usan datos de cualquier fuente.


9
2018-04-18 17:59



Tuve el problema en una lista de URL comenzando por %base_url% cuando quería hacer un sistema de conmutación por error.

Finalmente reemplazado %base_url% por #base_url# e hizo una resolución de marcador de posición manual en un servicio.

$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
2017-12-29 13:52



Creo que podemos agregar parámetros como funciones simples de clase a un servicio.

Esta es mi función de controlador.

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

Este es mi servicio

<?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
2018-01-26 06:58