php - parameter - symfony service loader
¿Cómo acceder al contenedor de servicios en la función global de symfony2(servicio)? (5)
No debe inyectar el service_container
en sus servicios. En su ejemplo, debería inyectar el antiguo security.context
o el security.token_storage
más reciente. Consulte, por ejemplo, la sección "Evitar que su código sea dependiente del contenedor" de http://symfony.com/doc/current/components/dependency_injection.html .
Ex:
<?php
namespace BizTV/CommonBundle/Helper;
use Symfony/Component/Security/Core/Authentication/Token/Storage/TokenStorage;
class globalHelper {
private $securityTokenStorage;
public function __construct(TokenStorage $securityTokenStorage) {
$this->securityTokenStorage= $securityTokenStorage;
}
public function hasAccess($container)
{
$user = $this->securityTokenStorage->getToken()->getUser();
//do my stuff
}
}
app / config / config.yml:
services:
biztv.helper.globalHelper:
class: BizTV/CommonBundle/Helper/globalHelper
arguments: [''@security.token_storage'']
Su controlador:
public function createAction($id) {
$helper = $this->get(''biztv.helper.globalHelper'');
$access = $helper->hasAccess($entity);
Esta pregunta comenzó cuando no entendía por qué no podía pasar variables a una función de ayuda global de symfony2 (servicio), pero gracias a las personas más brillantes que yo, me di cuenta de que mi error era tratar de usar el security_context desde una clase que no funcionaba. No lo he inyectado así que ...
Este es el resultado final, el código que funciona. No encontré una forma mejor de hacer que esto sea útil para la comunidad.
Así es como puede obtener el usuario y otros datos de security_context desde una función global o función auxiliar en symfony2.
Tengo la siguiente clase y función:
<?php
namespace BizTV/CommonBundle/Helper;
use Symfony/Component/DependencyInjection/ContainerInterface as Container;
class globalHelper {
private $container;
public function __construct(Container $container) {
$this->container = $container;
}
//This is a helper function that checks the permission on a single container
public function hasAccess($container)
{
$user = $this->container->get(''security.context'')->getToken()->getUser();
//do my stuff
}
}
... definido como un servicio (en app / config / config.yml) como este ...
#Registering my global helper functions
services:
biztv.helper.globalHelper:
class: BizTV/CommonBundle/Helper/globalHelper
arguments: [''@service_container'']
Ahora, en mi controlador llamo a esta función de esta manera ...
public function createAction($id) {
//do some stuff, transform $id into $entity of my type...
//Check if that container is within the company, and if user has access to it.
$helper = $this->get(''biztv.helper.globalHelper'');
$access = $helper->hasAccess($entity);
Otra opción es extender ContainerAware:
use Symfony/Component/DependencyInjection/ContainerAware;
class MyService extends ContainerAware
{
....
}
que le permite llamar a setContainer
en la declaración de servicio:
foo.my_service:
class: Foo/Bundle/Bar/Service/MyService
calls:
- [setContainer, [@service_container]]
A continuación, puede hacer referencia al contenedor en su servicio de esta manera:
$container = $this->container;
Supongo que el primer error (propiedad indefinida) sucedió antes de agregar la propiedad y el constructor. Entonces obtuviste el segundo error. Este otro error significa que su constructor espera recibir un objeto Container pero no recibió nada. Esto se debe a que cuando definió su servicio, no le dijo al administrador de Dependency Injection que quería obtener el contenedor. Cambie su definición de servicio a esto:
services:
biztv.helper.globalHelper:
class: BizTV/CommonBundle/Helper/globalHelper
arguments: [''@service_container'']
El constructor debería esperar un objeto de tipo Symfony / Component / DependencyInjection / ContainerInterface;
use Symfony/Component/DependencyInjection/ContainerInterface as Container;
class globalHelper {
private $container;
public function __construct(Container $container) {
$this->container = $container;
}
Tal vez no sea la mejor manera, pero lo que hago es pasar el contenedor a la clase, así que lo tengo cada vez que lo necesito.
$helpers = new Helpers();
or
$helpers = new Helpers($this->container);
/* My Class */
class Helpers
{
private $container;
public function __construct($container = null) {
$this->container = $container;
}
...
}
Siempre funciona para mí.
Un enfoque que siempre funciona, a pesar de no ser la mejor práctica en OO
global $kernel;
$assetsManager = $kernel->getContainer()->get(''acme_assets.assets_manager'');