【问题标题】:Symfony2 : extending FrameworkBundle ControllerSymfony2:扩展 FrameworkBundle 控制器
【发布时间】:2015-04-07 04:48:31
【问题描述】:

我有一个关于 Symfony2 控制器扩展的问题。目前,我一直在为我的应用程序中的每个控制器扩展一个 FrameworkBundle。但是我已经厌倦了总是通过制作一个

来检索用户
$this->get('security.context')->getToken()->getUser()

或者一个

$this->getDoctrine()->getEntityManager()

每次我需要用户或实体管理员时(我非常需要他们)。我希望能够通过执行 $this->em 和 $this->user 来检索它们。 所以我决定创建一个名为 MyApp/RootBundle 的包,其中包含一个扩展 FrameworkBundle 的新控制器。该控制器将被应用程序中的所有其他控制器扩展。这是代码:

<?php

namespace MyApp\RootBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\DependencyInjection\ContainerInterface;

class RootController extends Controller
{
    protected $em;

    protected $user;

    public function setContainer(ContainerInterface $container = null)
    {
        parent::setContainer($container);

        $this->onContainerSet();
    }

    public function onContainerSet()
    {
        $this->em = $this->getDoctrine()->getEntityManager();
        $this->user = $this->get('security.context')->getToken()->getUser();
    }
}

我无法在 __construct() 函数中加载 $this->em 和 $this->user,因为在构建时未加载容器。

所以我的问题是:

  • 这是个好主意还是我应该继续进行冗长的调用?
  • 创建功能相同的 getEm() 和 getUser() 会更好吗?

谢谢!

【问题讨论】:

    标签: controller symfony


    【解决方案1】:

    我遇到了同样的问题,我刚刚创建了一个具有 getUser()getEntityManager() 方法的自定义控制器。它完美地工作。在这种情况下,我建议使用 getter 方法而不是类实例,以与 Symfony2 期望您请求服务的方式保持一致。

    作为参考,这是我的 getUser 方法:

    public function getUser() {
            $user = $this->get('security.context')->getToken()->getUser();
            return $user;
    }
    

    【讨论】:

    • 好吧,我就是这么想的。制作“RootBundle”是否是个好主意?
    • 可以,但我将自定义控制器保存在供应商目录中。我没有看到需要将它放在自己的捆绑包中。无论哪种方式都应该可以正常工作,所以这取决于个人喜好。
    【解决方案2】:

    我创建了一个 MyController,还创建了一个 MyRepository。然后所有控制器和存储库扩展这些类。 我也调用 $this->getRepository("User"),而不是 $this->getDocrine()->getEntityManager()->getrepository("MyappBundle:User");

    【讨论】:

    • 好主意,我也会这样做:)
    • 这里是sn-p:public function getEm(){ return $this-&gt;getDoctrine()-&gt;getEntityManager(); } public function getRepository($shortEntityName){ return $this-&gt;getEm()-&gt;getRepository("SicoStockBundle:$shortEntityName"); }
    【解决方案3】:

    另一种选择是将控制器定义为服务,并将传递给构造函数的内容分配给您希望的任何私有变量,但缺点可能是您不喜欢此路由所需的所有设置

    【讨论】:

      【解决方案4】:

      即使没有控制器扩展,您也可以注入 EntityManager(或任何其他服务):

      use JMS\DiExtraBundle\Annotation as DI;
      
          class IndexController extends Controller 
          {  
             /**
               * @DI\Inject("doctrine.orm.entity_manager")
               * @var \Doctrine\ORM\EntityManager $em
               */
              protected $em;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-20
        • 2023-03-13
        • 2014-03-09
        • 2012-01-05
        相关资源
        最近更新 更多