这个问题始于我不理解为什么我不能将变量传递给symfony2全局帮助函数(服务),但是由于人们比我更亮,我意识到我的错误是试图从一个内部使用security_context没有注入的类......
这是最终结果,代码有效。我发现没有更好的办法让这对社区有帮助。
这是如何从symfony2中的全局函数或辅助函数中获取security_context中的用户和其他数据的。
我有以下课程和功能:
<?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);
答案 0 :(得分:83)
我假设在添加属性和构造函数之前发生了第一个错误(未定义属性)。然后你得到了第二个错误。这个其他错误意味着您的构造函数希望收到一个Container对象,但它什么也没收到。这是因为当您定义服务时,您没有告诉依赖注入管理器您想要获取容器。将您的服务定义更改为:
services:
biztv.helper.globalHelper:
class: BizTV\CommonBundle\Helper\globalHelper
arguments: ['@service_container']
然后构造函数应该期望一个Symfony \ Component \ DependencyInjection \ ContainerInterface类型的对象;
use Symfony\Component\DependencyInjection\ContainerInterface as Container;
class globalHelper {
private $container;
public function __construct(Container $container) {
$this->container = $container;
}
答案 1 :(得分:23)
一种始终有效的方法,尽管不是OO的最佳实践
global $kernel;
$assetsManager = $kernel->getContainer()->get('acme_assets.assets_manager');
答案 2 :(得分:8)
另一种选择是扩展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;
答案 3 :(得分:1)
也许这不是最好的方式,但我所做的是将容器传递给班级,所以每次我需要它时都会收到它。
$helpers = new Helpers();
or
$helpers = new Helpers($this->container);
/* My Class */
class Helpers
{
private $container;
public function __construct($container = null) {
$this->container = $container;
}
...
}
每次都适合我。
答案 4 :(得分:1)
您不应在服务中注入service_container
。在您的示例中,您应该注入旧的security.context
或更新的security.token_storage
。例如,参见&#34;避免您的代码依赖于容器&#34; 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
}
}
应用程序/配置/ 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);