54

这个问题始于我不明白为什么我不能将变量传递给 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);
4

5 回答 5

85

我假设第一个错误(未定义的属性)发生在您添加属性和构造函数之前。然后你得到了第二个错误。这个其他错误意味着您的构造函数希望接收一个 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;
    }
于 2012-08-21T14:26:43.267 回答
26

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

global $kernel;
$assetsManager = $kernel->getContainer()->get('acme_assets.assets_manager');‏
于 2014-04-01T21:40:57.833 回答
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;
于 2015-10-24T13:37:26.320 回答
1

也许这不是最好的方法,但我所做的是将容器传递给班级,所以每次我需要它时我都会拥有它。

$helpers = new Helpers();
or
$helpers = new Helpers($this->container);

/* My Class */
class Helpers
{
    private $container;

    public function __construct($container = null) {
        $this->container = $container;
    }
    ...
}

每次都为我工作。

于 2016-04-08T10:13:58.377 回答
1

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

应用程序/配置/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);
于 2016-10-27T14:59:21.813 回答