ZF2 - 服务管理器错误:工厂注册无效

时间:2014-05-02 21:25:19

标签: doctrine-orm zend-framework2

我使用以下教程来了解Doctrine的工作原理:http://doctrine-orm.readthedocs.org/en/latest/tutorials/getting-started.html

我现在对学说有了更好的理解。但是我很难理解实体经理以及如何使用它。

在获取实体管理器实例的教程中,您所做的只是:

$entityManager = \Doctrine\ORM\EntityManager::create($conn, $config);

它被加载到引导程序中,并且可以通过代码库获得。

所以我的问题是,如何在ZF2中实例化?

编辑:我通过ZF Talk获得了一些帮助,并向我推荐了以下内容。然而,我仍然在努力让它发挥作用:

我的目标是从我的数据库中提取一组用户,并使用Doctrines分页类将它们输出到我的视图。

在我的控制器中,我有给定的动作:

  public function usersAction() {
   $userFunctions = $this->getServiceLocator()->get('Administration\Model\UserFunctionFactory');
    $userArray = $userFunctions->getUsers();
    $viewModel = new ViewModel(array('users' => $userArray));
    return $viewModel;
}

用户功能模型如下:

namespace Administration\Model;
use Doctrine\ORM\Tools\Pagination\Paginator;

class UserFunctions
{

protected $em;

function __constructor(EntityManagerInterface $em) {
    $this->em = $em;
}

public function getUsers()
{
    $em = $this->em;

    $dql = "SELECT * FROM Users";
    $query = $em->createQuery($dql)
        ->setFirstResult(0)
        ->setMaxResults(100);

    $paginator = new Paginator($query, $fetchJoinCollection = true);

    $c = count($paginator);
    foreach ($paginator as $post) {
        $myArray[] = $post->getHeadline() . "\n";
    }
return $myArray;
}

}

SM的工厂:

<?php
namespace Administration\UserFunctionFactory;

use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Administration\Model\UserFunctions;

class UserFunctionsFactory implements FactoryInterface
{

    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $em = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
        return new UserFunctions($em);
    }
}

module.config:

    'service_manager' => array(
    'factories' => array(
        'Administration\Model\UserFunctionFactory' => 'Administration\Model\UserFunctionFactory')
),

我收到以下错误:

While attempting to create administrationmodeluserfunctionfactory(alias: Administration\Model\UserFunctionFactory) an invalid factory was registered for this instance type.

2 个答案:

答案 0 :(得分:2)

您的直接问题(基于您的代码段,以及由此产生的有关工厂无效的错误)实际上是微不足道的。

您的module.config.php表示工厂类是:

Administration\Model\UserFunctionFactory

但是工厂的类文件中定义的类的完全限定类名是:

Administration\UserFunctionFactory\UserFunctionFactory

命名空间不匹配意味着SM无法找到您的工厂。因此,您的第一个修复是确保您的工厂确实在Administration/src/Administration/Model/UserFunctionsFactory.php这样的文件中定义(假设您的模块使用的是PSR-0),并将第一行更改为namespace Administration/Model

答案 1 :(得分:1)

这是基本上你不应该在ZF2控制器中做的事情

$userFunctions = new UserFunctions();

相反,你创建一个服务(你的UserFunctions)并使用服务定位器在你的控制器中获取它

namespace Administration\Service;

use Zend\ServiceManager\FactoryInterface,
    Zend\ServiceManager\ServiceLocatorInterface;

use Administration\Model\UserFunctions;

class UserFunctionsFactory 
    implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        return new UserFunctions($this->getServiceLocator()->get('Doctrine\ORM\EntityManager'));
    }
}

所以你的用户函数类构造函数将是

use Doctrine\ORM\EntityManagerInterface;

// class declaration and props here

function __constructor(EntityManagerInterface $entityManager) {
     $this->em = $entityManager;
}

然后注册服务

// file services.config.php
namespace Administration;

return array(
    'factories' => array(
        'admin.service.contact' => new Service\UserFunctionsFactory()
    ),
);

请注意,您可以使用初始化程序进行注射,而不是使用类构造函数。为简单起见,我在上面的例子中使用了这种方法。

这是注入DoctrineEntityManager

的初始化程序的示例
namespace My\Service\Initializer;

use Zend\ServiceManager\InitializerInterface,
    Zend\ServiceManager\ServiceLocatorInterface,
    Zend\Debug\Debug;

    use My\Service\EntityManagerAwareInterface;

    class EntityManagerAwareInitializer 
        implements InitializerInterface
    {
        public function initialize($instance, ServiceLocatorInterface $serviceLocator) 
        {
            if($instance instanceof EntityManagerAwareInterface) {
                $instance->setEntityManager($serviceLocator->get('doctrine.entitymanager'));
            }
        }
    }

和界面

namespace My\Service;

use Doctrine\ORM\EntityManagerInterface;

interface EntityManagerAwareInterface 
{
    /**
     * Set Doctrine 2 Entity Manager
     * 
     * @param EntityManagerInterface $entityManager
     */
    function setEntityManager(EntityManagerInterface $entityManager);

    /**
     * Get Doctrine 2 Entity Manager
     */
    function getEntityManager();
}

和初始化程序的注册

'initializers' => array(
    'My\Service\Initializer\EntityManagerAwareInitializer' => new EntityManagerAwareInitializer()
),

请注意我已经分离了配置文件,因为我的模块实现了一些可以这样做的接口,例如

namespace My;

use Zend\ModuleManager\Feature\AutoloaderProviderInterface,
    Zend\ModuleManager\Feature\ControllerProviderInterface,
    Zend\ModuleManager\Feature\ServiceProviderInterface,
    Zend\ModuleManager\Feature\ConfigProviderInterface;

class Module 
    implements 
        AutoloaderProviderInterface,
        ControllerProviderInterface,
        ServiceProviderInterface,
        ConfigProviderInterface
{
    public function getConfig()
    {
        return include __DIR__ . '/../../config/module.config.php';
    }

    public function getControllerConfig()
    {
        return include __DIR__ . '/../../config/controllers.config.php';
    }

    public function getServiceConfig()
    {
        return include __DIR__ . '/../../config/services.config.php';
    }

    public function getAutoloaderConfig()
    {
        return array(
            'Zend\Loader\StandardAutoloader' => array(
                'namespaces' => array(
                    __NAMESPACE__ => __DIR__ . '/../../src/' . __NAMESPACE__,
                ),
            ),
        );
    }
}

我的Module.php在我的src中,所以要注意路径。

希望它有所帮助!

相关问题