如何在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);