将Doctrine实体管理器注入Zf2表单

时间:2013-07-29 13:25:55

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

我尝试以zf2形式注入doctrine实体管理器,方法如下所述 http://zf2cheatsheet.com/#doctrine(将实体管理器注入表单)但失败并显示错误_construct()必须是Doctrine \ ORM \ EntityManager的实例,null给定...

有人解决了这个问题吗?

1 个答案:

答案 0 :(得分:4)

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

/**             
 * @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 setter。

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,但是一旦我需要服务定位器,我就亲自创建一个工厂,我认为它不值得为服务创造大量开销。

我希望这有点帮助。