php 如何在 symfony2 全局辅助函数(服务)中访问服务容器?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12056178/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to access service container in symfony2 global helper function (service)?
提问by Matt Welander
This question started out with me not understanding why I couldn't pass variables to a symfony2 global helper function (service), but thanks to people brighter than I, I realized my error was about trying to use the security_context from within a class that didn't have it injected so...
这个问题一开始我不明白为什么我不能将变量传递给 symfony2 全局帮助函数(服务),但是多亏了比我聪明的人,我意识到我的错误是关于尝试在一个没有的类中使用 security_context没有注射所以...
This is the final result, the code that works. I found no better way of making this helpful to the comunity.
这是最终的结果,有效的代码。我发现没有更好的方法可以使这对社区有所帮助。
This is how you can get the user and other data from security_context from within a global function or helper function in symfony2.
这就是您如何从 symfony2 中的全局函数或辅助函数中的 security_context 中获取用户和其他数据的方法。
I have the following class and 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
}
}
...defined as a service (in app/config/config.yml) like this...
...定义为这样的服务(在 app/config/config.yml 中)...
#Registering my global helper functions
services:
biztv.helper.globalHelper:
class: BizTV\CommonBundle\Helper\globalHelper
arguments: ['@service_container']
Now, in my controller I call on this function like this...
现在,在我的控制器中,我像这样调用这个函数......
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);
回答by Carlos Granados
I assume that the first error (undefined property) happened before you added the property and the constructor. Then you got the second error. This other error means that your constructor expects to receive a Container object but it received nothing. This is because when you defined your service, you did not tell the Dependency Injection manager that you wanted to get the container. Change your service definition to this:
我假设第一个错误(未定义的属性)发生在您添加属性和构造函数之前。然后你得到了第二个错误。另一个错误意味着您的构造函数希望接收一个 Container 对象,但它什么也没收到。这是因为在定义服务时,您没有告诉依赖注入管理器您想要获取容器。将您的服务定义更改为:
services:
biztv.helper.globalHelper:
class: BizTV\CommonBundle\Helper\globalHelper
arguments: ['@service_container']
The constructor should then expect an object of type Symfony\Component\DependencyInjection\ContainerInterface;
构造函数应该期待一个 Symfony\Component\DependencyInjection\ContainerInterface 类型的对象;
use Symfony\Component\DependencyInjection\ContainerInterface as Container;
class globalHelper {
private $container;
public function __construct(Container $container) {
$this->container = $container;
}
回答by Guilherme Viebig
An approach that always works, despite not being the best practice in OO
尽管不是面向对象中的最佳实践,但始终有效的方法
global $kernel;
$assetsManager = $kernel->getContainer()->get('acme_assets.assets_manager');?
回答by Jonathan
Another option is to extend ContainerAware:
另一种选择是扩展 ContainerAware:
use Symfony\Component\DependencyInjection\ContainerAware;
class MyService extends ContainerAware
{
....
}
which allows you to call setContainerin the service declaration:
它允许您调用setContainer服务声明:
foo.my_service:
class: Foo\Bundle\Bar\Service\MyService
calls:
- [setContainer, [@service_container]]
You can then reference the container in your service like this:
然后,您可以像这样在您的服务中引用容器:
$container = $this->container;
回答by Strabek
Maybe it's not the best way but what I do is I pass container to the class so I have it every time I need it.
也许这不是最好的方法,但我所做的是将容器传递给班级,因此每次需要时我都可以使用它。
$helpers = new Helpers();
or
$helpers = new Helpers($this->container);
/* My Class */
class Helpers
{
private $container;
public function __construct($container = null) {
$this->container = $container;
}
...
}
Works every time for me.
每次都对我有用。
回答by Tsounabe
You should not inject the service_containerin your services. In your example you should rather inject the old security.contextor the more recent security.token_storageinstead. See for example the "Avoiding your Code Becoming Dependent on the Container" section of http://symfony.com/doc/current/components/dependency_injection.html.
你不应该service_container在你的服务中注入。在您的示例中,您应该改为注入旧的security.context或更新的security.token_storage。例如,参见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:
应用程序/配置/config.yml:
services:
biztv.helper.globalHelper:
class: BizTV\CommonBundle\Helper\globalHelper
arguments: ['@security.token_storage']
Your controller:
您的控制器:
public function createAction($id) {
$helper = $this->get('biztv.helper.globalHelper');
$access = $helper->hasAccess($entity);

