Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Symfony2:注入@security.context以获取当前用户。如何避免一个“错误”;ServiceCircularReferenceException;?注入整个容器?_Security_Symfony_Dependency Injection_Doctrine Orm - Fatal编程技术网

Symfony2:注入@security.context以获取当前用户。如何避免一个“错误”;ServiceCircularReferenceException;?注入整个容器?

Symfony2:注入@security.context以获取当前用户。如何避免一个“错误”;ServiceCircularReferenceException;?注入整个容器?,security,symfony,dependency-injection,doctrine-orm,Security,Symfony,Dependency Injection,Doctrine Orm,在解决问题之后,我遇到了另一个问题/安全问题/问题 正如您在另一篇文章中看到的,我试图在侦听器中注入安全上下文,但如果我不碰代码,就不动代码,则会出现以下错误: ServiceCircularReferenceException:检测到的循环引用 服务“条令.orm.default\u实体\u管理器” 因此,通过阅读和研究,我找到了一个解决方案,但我不清楚我的应用程序是否正确或安全。这就是我所做的: 我没有注入[@security.context]而是这样做: services: ord

在解决问题之后,我遇到了另一个问题/安全问题/问题

正如您在另一篇文章中看到的,我试图在侦听器中注入安全上下文,但如果我不碰代码,就不动代码,则会出现以下错误:

ServiceCircularReferenceException:检测到的循环引用 服务“条令.orm.default\u实体\u管理器”

因此,通过阅读和研究,我找到了一个解决方案,但我不清楚我的应用程序是否正确或安全。这就是我所做的:

我没有注入
[@security.context]
而是这样做:

services:
    orderhascomment.listener:
        class: PL\OrderBundle\Listener\OrderHasCommentListener
        arguments: [@service_container]
        tags:
            - { name: doctrine.event_listener, event: prePersist, method: onPrePersist }
我的listener
OrderHasCommentListener.php
如下所示:

namespace PL\OrderBundle\Listener;

use Doctrine\ORM\Event\LifecycleEventArgs;
use Symfony\Component\DependencyInjection\ContainerInterface;

class OrderHasCommentListener {

    protected $container;

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

    /**
     *
     * @param LifecycleEventArgs $args 
     */
    public function onPrePersist(LifecycleEventArgs $args) {

        $entity = $args->getEntity();
        $user = $this->container->get('security.context')->getToken()->getUser();
        $entity->setUser($user);
    }

}
这样做对吗?还是存在另一个?我读到注入整个容器是个坏主意,因为我只需要安全上下文,那么解决方案是什么?()

尝试转换服务中的UserCallable

我正试图在服务中转换
UserCallable
,方法是按照说明进行转换,并查看和了解他们是如何进行转换的,但由于出现以下错误,我无法使其正常工作:

ContextErrorException:可捕获致命错误:参数1传递给 PL\OrderBundle\Listener\OrderHasCommentListener::\uu构造()必须为 可调用,字符串给定

这就是我在
app/config/config.yml中的定义:

services:
    orderhascomment.listener:
        class: PL\OrderBundle\Listener\OrderHasCommentListener
        arguments: 
            - user_callable
        tags:
            - { name: doctrine.event_listener, event: prePersist, method: onPrePersist }
    user_callable:
        class: PL\OrderBundle\Util\UserCallable
        arguments:
            - "@service_container"
        public:  false
这就是我如何在
OrderHasCommentListener.php
文件中传递到
\u construct()
函数的方法:

/**
 * @param UserCallableInterface $user_callable 
 * */
public function __construct(callable $user_callable = null) {
    $this->userCallable = $user_callable;
}

怎么了?

将整个容器直接注入列表器可能是一个有效的解决方案。。。但我们可以做得更好:)

插入一个
UserCallable
,返回当前用户

通过这种方式,您可以更清楚地表达依赖性的真正目的,而无需在侦听器和容器(-interface)之间引入硬依赖性。例如

通过创建一个接口并将其用于侦听器中的类型暗示,可以进一步改进这个特定示例。如果您计划重新使用侦听器,那么可以更容易地进行交换

接口:

namespace Acme\Common;

interface UserCallableInterface
{
    /**
     * @return \Symfony\Component\Security\Core\User\UserInterface
     */
    public function getCurrentUser();
}
namespace Acme\Util;

use Acme\Common\UserCallableInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

class UserCallable implements UserCallableInterface
{
   /** @var ContainerInterface **/
   protected $container;

   /** 
    * @param ContainerInterface $container
    */
   public function __construct(ContainerInterface $container)
   {
      $this->container = $container;
   }

   /**
    * @{inheritdoc}
    */
   public function getCurrentUser()
   {
      return $this->container->get('security.context')->getToken()->getUser() ?: false;
   }
use Acme\Common\UserCallableInterface;
use Acme\Common\TrackableInterface;
use Doctrine\Common\EventArgs;

class Listener
{
    /** @var UserCallableInterface **/
    protected $userCallable;

    /** 
     * @param UserCallableInterface $user_callable 
     **/    
    public function __construct(UserCallableInterface $user_callable)
    {
       $this->userCallable = $user_callable;
    }

    /** 
     * @param EventArgs $args 
     **/
    public function onPrePersist(EventArgs $args)
    {
       $entity = $args->getEntity();

       if ( !($entity instanceof TrackableInterface) ) {
           return;
       }

       if ( !($user = $this->userCallable->getCurrentUser())) {
           return;
       }

       $entity->setUser($user);
    }      
}

用户可调用:

namespace Acme\Common;

interface UserCallableInterface
{
    /**
     * @return \Symfony\Component\Security\Core\User\UserInterface
     */
    public function getCurrentUser();
}
namespace Acme\Util;

use Acme\Common\UserCallableInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

class UserCallable implements UserCallableInterface
{
   /** @var ContainerInterface **/
   protected $container;

   /** 
    * @param ContainerInterface $container
    */
   public function __construct(ContainerInterface $container)
   {
      $this->container = $container;
   }

   /**
    * @{inheritdoc}
    */
   public function getCurrentUser()
   {
      return $this->container->get('security.context')->getToken()->getUser() ?: false;
   }
use Acme\Common\UserCallableInterface;
use Acme\Common\TrackableInterface;
use Doctrine\Common\EventArgs;

class Listener
{
    /** @var UserCallableInterface **/
    protected $userCallable;

    /** 
     * @param UserCallableInterface $user_callable 
     **/    
    public function __construct(UserCallableInterface $user_callable)
    {
       $this->userCallable = $user_callable;
    }

    /** 
     * @param EventArgs $args 
     **/
    public function onPrePersist(EventArgs $args)
    {
       $entity = $args->getEntity();

       if ( !($entity instanceof TrackableInterface) ) {
           return;
       }

       if ( !($user = $this->userCallable->getCurrentUser())) {
           return;
       }

       $entity->setUser($user);
    }      
}
听众:

namespace Acme\Common;

interface UserCallableInterface
{
    /**
     * @return \Symfony\Component\Security\Core\User\UserInterface
     */
    public function getCurrentUser();
}
namespace Acme\Util;

use Acme\Common\UserCallableInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

class UserCallable implements UserCallableInterface
{
   /** @var ContainerInterface **/
   protected $container;

   /** 
    * @param ContainerInterface $container
    */
   public function __construct(ContainerInterface $container)
   {
      $this->container = $container;
   }

   /**
    * @{inheritdoc}
    */
   public function getCurrentUser()
   {
      return $this->container->get('security.context')->getToken()->getUser() ?: false;
   }
use Acme\Common\UserCallableInterface;
use Acme\Common\TrackableInterface;
use Doctrine\Common\EventArgs;

class Listener
{
    /** @var UserCallableInterface **/
    protected $userCallable;

    /** 
     * @param UserCallableInterface $user_callable 
     **/    
    public function __construct(UserCallableInterface $user_callable)
    {
       $this->userCallable = $user_callable;
    }

    /** 
     * @param EventArgs $args 
     **/
    public function onPrePersist(EventArgs $args)
    {
       $entity = $args->getEntity();

       if ( !($entity instanceof TrackableInterface) ) {
           return;
       }

       if ( !($user = $this->userCallable->getCurrentUser())) {
           return;
       }

       $entity->setUser($user);
    }      
}

嗯,我以前从来没有这样做过,所以我完全不明白这一点也许一段使用Listener或Entity的代码会对我有更好的帮助(我是新手),所以希望你能帮助我,你还不清楚什么?我很乐意改进我的答案。我尝试了你的代码,得到了这个错误
ContextErrorException:可捕获的致命错误:传递给PL\OrderBundle\Listener\OrderHasCommentListener的参数1::\uu construct()必须是PL\OrderBundle\UserCallableInterface的实例,给定的AppDevDebBugProjectContainer实例
OK-您需要将usercallable转换为服务,并注入此服务而不是容器。这是这种方法的关键所在。我将添加一些说明并重新编写答案-挂起:)顺便说一句,使用
$this->container->get('security.authorization\u checker')
(2.6中新增)请参见此处的“security.token\u storage”解决方案: