如何在symfony2全局帮助函数(服务)中访问服务容器?

这个问题始于我不明白为什么我不能将variables传递给symfony2全局帮助函数(service),但是由于比我更亮的人,我意识到我的错误是关于尝试从类中使用security_context没有注入所以…

这是最后的结果,代码是有效的。 我发现没有更好的方法使这对社区有帮助。

这是如何从symfony2中的全局函数或帮助函数中获取来自security_context的用户和其他数据。

我有以下类和function:

<?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 } } 

…定义为一个服务(在app / config / config.yml)像这样…

 #Registering my global helper functions services: biztv.helper.globalHelper: class: BizTV\CommonBundle\Helper\globalHelper arguments: ['@service_container'] 

现在,在我的控制器中,我调用这个函数,像这样…

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

我假设在添加属性和构造函数之前发生了第一个错误(未定义属性)。 然后你得到第二个错误。 这另一个错误意味着你的构造函数期望收到一个Container对象,但它什么都没收到。 这是因为当你定义你的服务时,你没有告诉dependency injectionpipe理器你想获得容器。 将您的服务定义更改为:

 services: biztv.helper.globalHelper: class: BizTV\CommonBundle\Helper\globalHelper arguments: ['@service_container'] 

然后构造函数应该期望一个Symfony \ Component \ DependencyInjection \ ContainerInterfacetypes的对象;

 use Symfony\Component\DependencyInjection\ContainerInterface as Container; class globalHelper { private $container; public function __construct(Container $container) { $this->container = $container; } 

尽pipe不是面向对象的最佳实践,但这种方法始终有效

 global $kernel; $assetsManager = $kernel->getContainer()->get('acme_assets.assets_manager');‏ 

另一种select是扩展ContainerAware:

 use Symfony\Component\DependencyInjection\ContainerAware; class MyService extends ContainerAware { .... } 

它允许你在服务声明中调用setContainer

 foo.my_service: class: Foo\Bundle\Bar\Service\MyService calls: - [setContainer, [@service_container]] 

然后你可以像这样在你的服务中引用容器:

 $container = $this->container; 

也许这不是最好的方法,但我所做的是将容器传递给课堂,所以我每次都需要它。

 $helpers = new Helpers(); or $helpers = new Helpers($this->container); /* My Class */ class Helpers { private $container; public function __construct($container = null) { $this->container = $container; } ... } 

每次为我工作。

你不应该在服务中注入service_container 。 在你的例子中,你应该注入旧的security.context或更新的security.token_storage 。 请参阅http://symfony.com/doc/current/components/dependency_injection.html中的“避免代码取决于容器”部分。;

例如:

 <?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 } } 

应用程序/configuration/ config.yml:

 services: biztv.helper.globalHelper: class: BizTV\CommonBundle\Helper\globalHelper arguments: ['@security.token_storage'] 

你的控制器:

 public function createAction($id) { $helper = $this->get('biztv.helper.globalHelper'); $access = $helper->hasAccess($entity);