【问题标题】:How to call Entity Manager in a constructor?如何在构造函数中调用实体管理器?
【发布时间】:2014-01-02 10:51:53
【问题描述】:

我一直在尝试在构造函数中调用Entity Manager

function __construct()
{
    $this->getDoctrine()->getEntityManager();
    ...

但是,正如我在这个答案中看到的:Stackoverflow question,它无法完成。

所以想知道有没有办法实现它,因为我经常调用它,并且想在获取存储库后在构造函数中做一些事情。

编辑:

我试过@MKhalidJunaid 回答:

//src/MSD/HomeBundle/Resources/config/services.yml
services:
  imageTransController.custom.service:
    class:  MSD\HomeBundle\Controller\ImageTransController
    arguments: 
        EntityManager: "@doctrine.orm.entity_manager"

-

//app/config/config.php
imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: doctrine_extensions.yml }
- { resource: "@MSDHomeBundle/Resources/config/services.yml" }

-

//src/MSD/HomeBundle/Controller/ImageTransController.php
namespace MSD\HomeBundle\Controller;

use Doctrine\ORM\EntityManager;
use MSD\HomeBundle\Entity\Imagen as Imagen;
use MSD\HomeBundle\Controller\HomeController as HomeController;


class ImageTransController extends HomeController
{
    protected $em ;

    function __construct(EntityManager $entityManager)
    {
    ...

但我收到此错误:

Catchable Fatal Error: Catchable Fatal Error: Argument 1 passed to MSD\HomeBundle\Controller\ImageTransController::__construct() must be an instance of Doctrine\ORM\EntityManager, none given, called in /home/manolo/MiServer/itransformer/app/cache/dev/jms_diextra/controller_injectors/MSDHomeBundleControllerImageTransController.php on line 13 and defined in /home/manolo/MiServer/itransformer/src/MSD/HomeBundle/Controller/ImageTransController.php line 38 (500 Internal Server Error)

新尝试:

我也试过@praxmatig 回答:

//services.yml
parameters:
 msd.controller.imagetrans.class: MSD\HomeBundle\Controller\ImageTransController

services:
  msd.imagetrans.controller:
    class:  "%msd.controller.imagetrans.class%"
    arguments: [ @doctrine.orm.entity_manager  ]

-

//ImageTransController.php
namespace MSD\HomeBundle\Controller;

 use Doctrine\ORM\EntityManager;

class ImageTransController 
 {
    protected $em ;

    function __construct(EntityManager $em)
    {
        $this->em = $em;
    }
     ...

-

//routing.yml
msd_home_cambiardimensiones:
    pattern: /cambiardimensiones
    defaults: { _controller: MSDHomeBundle:msd.imagetrans.controller:cambiardimensionesAction }

但我收到此错误:

 Unable to find controller "MSDHomeBundle:msd.imagetrans.controller" - class "MSD\HomeBundle\Controller\msd.imagetrans.controllerController" does not exist. (500 Internal Server Error)

【问题讨论】:

  • @MKhalidJunaid - 如果在构造函数之后注入EntityManager,我如何将EntityManager 作为构造函数中的参数传递?能发个详细的答案吗?
  • 这就是依赖注入,因为它是在构造函数调用以访问构造函数中的实体管理器后注入的,您需要创建服务并将其作为参数传递,请参阅下面的答案,它会给您一个想法

标签: php symfony constructor entitymanager


【解决方案1】:

您需要为您的班级创建一个服务,并将理论实体管理器作为参数 doctrine.orm.entity_manager.Like 在 services.yml 中传递

services:
  test.cutom.service:
    class:  Test\YourBundleName\Yourfoldernameinbundle\Test
    #arguments:
    arguments: [ @doctrine.orm.entity_manager  ] 
        #entityManager: "@doctrine.orm.entity_manager"

您必须在 config.yml 中导入您的 services.yml

imports:
    - { resource: "@TestYourBundleName/Resources/config/services.yml" }

然后在你的类的构造函数中获取实体管理器作为参数

use Doctrine\ORM\EntityManager;
Class Test {

  protected $em;

  public function __construct(EntityManager $entityManager)
  {
    $this->em = $entityManager;
  }
}

希望这是有道理的

【讨论】:

  • 是的,确实如此。让我明天在标记为已回答之前尝试。感谢您的详细解答。
  • 好吧,如果我喜欢你的话,我会收到这个错误:Catchable Fatal Error: Argument 1 passed to MSD\HomeBundle\Controller\ImageTransController::__construct() must be an instance of MSD\HomeBundle\Controller\EntityManager, none given, called in /home/xxxx/webDir/itransformer/app/cache/dev/jms_diextra/controller_injectors/MSDHomeBundleControllerImageTransController.php on line 13 and defined in /home/xxxx/webDir/itransformer/src/MSD/HomeBundle/Controller/ImageTransController.php line 37 (500 Internal Server Error)。知道还需要做什么吗?
  • 您是否在 config.yml 中正确导入了您的服务
  • 是的,就像你说的:{ resource: "@MSDHomeBundle/Resources/config/services.yml" }。如果我改变一个词,我会得到一个错误,所以我猜它是正确的。问题似乎来自services.yml:services: imagetrans.custom.service: class: MSD\HomeBundle\Controller\ImageTransController arguments: entityManager: "@doctrine.orm.entity_manager"
  • 我已经编辑了我的问题。也许你能找到错字。
【解决方案2】:

当您将控制器注册为服务时,不要扩展基本控制器类。有一个关于它的文档here

class ImageTestController
{
     private $em;

     public function __construct(EntityManager $em)
     {
         $this->em = $em;
     }

     public function someAction()
     {
         // do something with $this->em
     }
}

// services.yml
services:
    acme.controller.image_test:
        class: Acme\SomeBundle\Controller\ImageTestController

// routing.yml
acme:
    path: /
    defaults: { _controller: acme.controller.image_test:someAction }

【讨论】:

  • @ManoloSalsas 将 defaults: { _controller: MSDHomeBundle:msd.imagetrans.controller:cambiardimensionesAction } 替换为 defaults: { _controller: msd.imagetrans.controller:cambiardimensionesAction }。如果要将控制器用作服务,则不应指定捆绑名称。
  • 这里添加了,我建议尽可能避免使用实体管理器。使用 ObjectManager 或 EntityManagerInterface。对象管理器应该能够进行必要的刷新和提交。如果您想选择东西,我建议您使用客户存储库并将其传递。 docs.doctrine-project.org/en/2.0.x/reference/… 然后你可以把这个对象作为构造函数一起传递。
  • 我决定不以这种方式使用 EM,但您的回答给了我错字。你是赢家 :) 但我会将前一个标记为已回答,它具有原始答案。
【解决方案3】:

为什么要在控制器的构造函数中获取 Doctrine 2 EntityManager?

为什么不在您需要的操作中简单地执行$em = $this->getDoctrine()->getManager();(或Symfony 2.0 中的$em = $this->getDoctrine()->getEntityManager();)?这样可以节省您在不需要时初始化 EntityManager 的开销。

如果你真的想这样做,How to define Controllers as Services 上有明确的说明。基本上是这样的:

# src/MSD/HomeBundle/Controller/ImageTransController.php

namespace MSD\HomeBundle\Controller;

use Doctrine\ORM\EntityManager;

class ImageTransController
{
    private $em;

    public function __construct(EntityManager $em)
    {
        $this->em = $em;
    }

    public function indexAction()
    {
        // use $this->em
    }
}


# src/MSD/HomeBundle/Resources/config/services.yml

parameters:
    msd.controller.image_trans.class: MSD\HomeBundle\Controller\ImageTransController

services:
    msd.controller.image_trans:
        class:     "%msd.controller.image_trans.class%"
        arguments: ["@doctrine.orm.default_entity_manager"]

# app/config/routing.yml

msd_home_cambiardimensiones:
    path:         /cambiardimensiones
    defaults:     { _controller: msd.controller.image_trans:indexAction }

【讨论】:

    【解决方案4】:

    你必须添加

    use Doctrine\ORM\EntityManager;
    

    在你的控制器中

    【讨论】:

      【解决方案5】:

      我看到您试图在控制器的构造函数中获取实体管理器,这不是这样做的方法,除非您打算将控制器定义为服务。 在这种情况下,您需要使用依赖注入来注入服务实体管理器。

      但一般来说,在控制器中使用实体管理器的常用方法是使用以下代码获取它:

        $entityManager = $this->container->get('doctrine.orm.entity_manager');
      

      【讨论】:

        【解决方案6】:

        我认为你的方向是正确的,我会选择第二个选项:

        对于第二个选项,我认为 routing.yml 里面的定义是错误的

        //routing.yml 
        msd_home_cambiardimensiones:
            pattern: /cambiardimensiones
            defaults: { _controller: msd.imagetrans.controller:cambiardimensionesAction }
        

        这里只是从默认值中的_controller中删除MSDHomeBundle

        对于第一个选项:

        HomeController 有自己的构造函数吗?

        //src/MSD/HomeBundle/Resources/config/services.yml
        services:
            imageTransController.custom.service:
                class:  MSD\HomeBundle\Controller\ImageTransController
                arguments: [@doctrine]
        

        它可以在构造函数中提供帮助

        __construct(Registry $doctrine)
        $this->doctrine = $doctrine;
        
        or
        
        $this->em = $doctrine->getManager();
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-03-14
          • 2015-12-18
          • 1970-01-01
          • 1970-01-01
          • 2011-09-14
          • 2020-10-23
          • 1970-01-01
          • 2014-08-30
          相关资源
          最近更新 更多