【问题标题】:Inject Doctrine Entity Manager to Zf2 Form将 Doctrine Entity Manager 注入 Zf2 表单
【发布时间】:2013-07-29 07:40:11
【问题描述】:

我尝试按照此处描述的方式以 zf2 形式注入理论实体管理器 http://zf2cheatsheet.com/#doctrine (Inject the Entity Manager to Form) 但失败并出现错误 _construct() must be an instance of Doctrine\ORM\EntityManager, null given...

有人解决了这个问题吗?

【问题讨论】:

  • 你能发布你的代码吗
  • 一些代码将帮助我们指导您

标签: zend-framework doctrine-orm zend-framework2 zend-form


【解决方案1】:

有几种方法可以做到这一点。肮脏但更简单的方法是在您的控制器操作中提供表单实体管理器通过这样的参数:

/**             
 * @var Doctrine\ORM\EntityManager
 */                
protected $em;

public function getEntityManager()
{
    if (null === $this->em) {
        $this->em = $this->getServiceLocator()->get('doctrine.entitymanager.orm_default');
    }
    return $this->em;
}

public function setEntityManager(EntityManager $em)
{
    $this->em = $em;
}
...
public function yourAction() {
...
   $form = new YourForm($this->getEntityManger());
...
}

然后您可以在表单中调用实体管理器方法:

public function __construct($em)
{
...
   $repository = $em->getRepository('\Namespace\Entity\Namespace');
...
}

更复杂但更好的方法需要您在模块 Module.php 中添加 getServiceconfig 函数:

public function getServiceConfig()
{
    return array(
        'factories' => array(
            'YourFormService' => function ($sm) {
                $form = new YourForm($sm);
                $form->setServiceManager($sm);
                return $form;
            }
        )
    );
}

在您的表单中,您需要实现 ServiceManagerAwareInterface 和 setServiceManager 设置器。

use Zend\Form\Form as BaseForm;
use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\ServiceManagerAwareInterface;

class CategoryForm extends BaseForm implements ServiceManagerAwareInterface
{
protected $sm;

public function setServiceManager(ServiceManager $sm)
{
    $this->sm = $sm;
}

public function __construct($sm)
{
...
$em = $sm->get('Doctrine\ORM\EntityManager');
...
}

然后您必须在控制器中以不同的方式调用您的表单。通常的$form = new YourForm(); 构造函数不适用于我们创建的工厂。

$form = $this->getServiceLocator()->get('YourFormService');

我通常使用肮脏的方式来获取 Entitymanager,但是一旦我需要服务定位器,我就亲自创建了一个工厂,我认为用服务创建大量开销是不值得的。

我希望这会有所帮助。

【讨论】:

  • 使用选项 2 并仅注入实体管理器将是最好的方法,没有必要注入整个服务管理器。
  • 非常感谢大家的回答!我尝试了第一种方法,但它给了我错误 - “_construct() 必须是 Doctrine\ORM\EntityManager 的一个实例,给定空值......”。稍后我将使用 serviceManager 尝试第二种方法(现在我有点忙),我会评论结果。
  • 您不必在对象上手动设置服务定位器()。如果 class 是 instanceof ServiceLocatorAwareInterface,则最好将此服务注册为可调用而不是工厂。服务管理器会自动注入 ServiceLocator。
  • @takeshin 我还没有机会使用 zf3。如果我这样做了,我肯定会更新这个答案,因为它也被标记为 zendframework。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-30
相关资源
最近更新 更多