Symfony 2.4.2 - 在不同捆绑包中的控制器之间传递实体管理器

时间:2014-02-20 22:56:39

标签: entitymanager symfony-2.4

我遇到了在两层控制器之间传递实体管理器的问题。

我正在构建的系统具有以下结构:

2捆绑:

Core Bundle (我们称之为后端控制器)

这是包含所有模型(实体)和业务规则/逻辑的包。

API Bundle (称之为前端控制器)

负责检查传入的api密钥的权限,并与Core bundle通信以获取信息。

以下是用户控制器和实体的示例:

APIBundle中的

UserController.php

<?php

namespace Acme\Bundle\APIBundle\Controller;

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;

use Acme\Bundle\CoreBundle\Controller\UserController as User;


use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class UserController extends BaseController implements AuthenticatedController
{

    public function readAction(Request $request) {

        $user = new User($this->getDoctrine()->getManager());

        $user->load(2);

        return $this->response($user);
    }
}
CoreBundle中的

UserController.php

<?php

namespace Acme\Bundle\CoreBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\Response;

use Acme\Bundle\CoreBundle\Entity\User;

class UserController extends BaseController
{

    function __construct($em) {
        parent::__construct($em);
        $this->entity = new User();
    }

    /**
     * Get userId
     *
     * @return integer 
     */
    public function getUserId()
    {
        return $this->entity->userId;
    }

    /**
     * Set firstName
     *
     * @param string $firstName
     * @return User
     */
    public function setFirstName($firstName)
    {
        $this->entity->firstName = $firstName;

        return $this;
    }

    // ...
    public function load($id) {

    if (!$this->entity instanceof \Acme\Bundle\CoreBundle\Entity\BaseEntity) {
        throw new \Exception('invalid entity argument');
    }

    $this->entity = $this->em->getRepository('AcmeCoreBundle:User')->find($id);
    }
}

请告诉我,如果我这样做的话。每次在控制器之间传递实体管理器似乎很奇怪。

也许有更好的方法可以做到这一点?

分离捆绑包之间的想法是否有意义?

谢谢,非常感谢您的每一个想法。

2 个答案:

答案 0 :(得分:1)

如果从未通过HTTP访问CoreBundle UserController,它的方法也不会返回Symfony \ Component \ HttpFoundation \ Response的实例,那么它实际上并不是一个控制器。

您最好将其定义为服务,如在CoreBundle \ Service \ User中,并通过DI容器注入EntityManager。

sevices.yml

  corebundle.userservice:
    class:  Acme\CoreBundle\Service\User
    arguments: [@doctrine.orm.entity_manager]

然后可以从Acme \ Bundle \ APIBundle \ Controller \ UserController获得以下内容:

$user = $this->get('corebundle.userservice');

当然,你也可以自己定义Acme \ Bundle \ APIBundle \ Controller \ UserController作为服务,然后为方便起见注入'corebundle.userservice'。

我建议您阅读Dependency Injection上的Symfony文档。

答案 1 :(得分:-1)

在Entity类中搜索获取实体管理器是错误的方法!

在CoreBundle中,您使用与实体类相同的UserController.php。

阅读docs以了解如何在symfony中正确使用存储库。

在APIBundle的UserController中,您必须调用自定义存储库函数。此存储库在您的实体中声明。