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

Mat*_*der 54 php service symfony

这个问题始于我不理解为什么我不能将变量传递给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
    }     
}
Run Code Online (Sandbox Code Playgroud)

...定义为服务(在app/config/config.yml中),就像这样......

#Registering my global helper functions            
services:
  biztv.helper.globalHelper:
    class: BizTV\CommonBundle\Helper\globalHelper
    arguments: ['@service_container']
Run Code Online (Sandbox Code Playgroud)

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

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);
Run Code Online (Sandbox Code Playgroud)

Car*_*dos 84

我假设在添加属性和构造函数之前发生了第一个错误(未定义属性).然后你得到了第二个错误.这个其他错误意味着您的构造函数希望收到一个Container对象,但它什么也没收到.这是因为当您定义服务时,您没有告诉依赖注入管理器您想要获取容器.将您的服务定义更改为:

services:
  biztv.helper.globalHelper:
    class: BizTV\CommonBundle\Helper\globalHelper
    arguments: ['@service_container']
Run Code Online (Sandbox Code Playgroud)

然后构造函数应该期望Symfony\Component\DependencyInjection\ContainerInterface类型的对象;

use Symfony\Component\DependencyInjection\ContainerInterface as Container;

class globalHelper {    

    private $container;

    public function __construct(Container $container) {
        $this->container = $container;
    }
Run Code Online (Sandbox Code Playgroud)

  • 注入`Container`是一个主要的内存泄漏,而是注入所需的服务,而不是所有的容器. (4认同)

Gui*_*big 23

尽管不是OO中的最佳实践,但这种方法始终有效

global $kernel;
$assetsManager = $kernel->getContainer()->get('acme_assets.assets_manager');?
Run Code Online (Sandbox Code Playgroud)

  • 有时Symfony会让OO接近你想要做的事情.谢谢你! (13认同)

Jon*_*han 8

另一个选择是扩展ContainerAware:

use Symfony\Component\DependencyInjection\ContainerAware;

class MyService extends ContainerAware
{
    ....
}
Run Code Online (Sandbox Code Playgroud)

它允许您调用setContainer服务声明:

foo.my_service:
    class: Foo\Bundle\Bar\Service\MyService
    calls:
        - [setContainer, [@service_container]]
Run Code Online (Sandbox Code Playgroud)

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

$container = $this->container;
Run Code Online (Sandbox Code Playgroud)