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



我按照下面的教程来理解Doctrine是如何工作的:http://doctrine-orm.readthedocs.org/en/latest/tutorials/getting-started.html

我现在对学说有了更好的理解。然而,我正在努力理解实体管理器以及如何使用它。

在本教程中,要获取实体管理器的实例,您只需执行以下操作:

$entityManager = DoctrineORMEntityManager::create($conn, $config);

加载在引导程序中,并且可以在整个代码库中使用。

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

编辑:我通过ZF Talk得到了一些帮助,下面是推荐给我的。然而,我仍然在努力让它工作:

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

在我的控制器中,我有:

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

用户函数模型如下:

namespace AdministrationModel;
use DoctrineORMToolsPaginationPaginator;
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 AdministrationUserFunctionFactory;
use ZendServiceManagerFactoryInterface;
use ZendServiceManagerServiceLocatorInterface;
use AdministrationModelUserFunctions;
class UserFunctionsFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $em = $this->getServiceLocator()->get('DoctrineORMEntityManager');
        return new UserFunctions($em);
    }
}

module.config:

    'service_manager' => array(
    'factories' => array(
        'AdministrationModelUserFunctionFactory' => 'AdministrationModelUserFunctionFactory')
),

我得到以下错误:

While attempting to create administrationmodeluserfunctionfactory(alias: AdministrationModelUserFunctionFactory) an invalid factory was registered for this instance type.

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

你的module.config.php说工厂类是:

AdministrationModelUserFunctionFactory

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

AdministrationUserFunctionFactoryUserFunctionFactory

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

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

$userFunctions = new UserFunctions();
相反,你创建一个服务(你的UserFunctions),并使用服务定位符 在你的控制器中获取它
namespace AdministrationService;
use ZendServiceManagerFactoryInterface,
    ZendServiceManagerServiceLocatorInterface;
use AdministrationModelUserFunctions;
class UserFunctionsFactory 
    implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        return new UserFunctions($this->getServiceLocator()->get('DoctrineORMEntityManager'));
    }
}

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

use DoctrineORMEntityManagerInterface;
// 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 ServiceUserFunctionsFactory()
    ),
);

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

这是一个初始化器注入DoctrineEntityManager

的例子
namespace MyServiceInitializer;
use ZendServiceManagerInitializerInterface,
    ZendServiceManagerServiceLocatorInterface,
    ZendDebugDebug;
    use MyServiceEntityManagerAwareInterface;
    class EntityManagerAwareInitializer 
        implements InitializerInterface
    {
        public function initialize($instance, ServiceLocatorInterface $serviceLocator) 
        {
            if($instance instanceof EntityManagerAwareInterface) {
                $instance->setEntityManager($serviceLocator->get('doctrine.entitymanager'));
            }
        }
    }

和接口

namespace MyService;
use DoctrineORMEntityManagerInterface;
interface EntityManagerAwareInterface 
{
    /**
     * Set Doctrine 2 Entity Manager
     * 
     * @param EntityManagerInterface $entityManager
     */
    function setEntityManager(EntityManagerInterface $entityManager);
    /**
     * Get Doctrine 2 Entity Manager
     */
    function getEntityManager();
}

和初始化器

的注册
'initializers' => array(
    'MyServiceInitializerEntityManagerAwareInitializer' => new EntityManagerAwareInitializer()
),

请注意,我有分离的配置文件,因为我的模块实现了一些接口,提供了这样做的可能性,例如

namespace My;
use ZendModuleManagerFeatureAutoloaderProviderInterface,
    ZendModuleManagerFeatureControllerProviderInterface,
    ZendModuleManagerFeatureServiceProviderInterface,
    ZendModuleManagerFeatureConfigProviderInterface;
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(
            'ZendLoaderStandardAutoloader' => array(
                'namespaces' => array(
                    __NAMESPACE__ => __DIR__ . '/../../src/' . __NAMESPACE__,
                ),
            ),
        );
    }
}

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

希望有帮助!

最新更新