5

我刚刚开始为一个新项目设置一个新的 ZF2 应用程序,基于 ZF2 骨架,并且正在查看他们关于Models的教程。

tl;dr:我应该如何在多个不同的模块之间共享一个模型,把它放在更高级别的某个地方(/模块之外)?

我们有几个模块设置如下:

/
/module/ModuleName
/module/ModuleName/config
/module/ModuleName/src
/module/ModuleName/src/ModuleName

我正要设置一个文件夹/module/ModuleName/src/ModuleName/Model/TableName.php,但后来我意识到:该表也需要在其他模块中访问。所以我该怎么做?

我应该将 Models 文件夹放入/module/Model还是会导致它被视为模块,即 site.com/model (基于我们当前的配置,它会)。

我应该在地方之间复制和粘贴模型吗?我应该把模型放回/vendor/library/Company/Model某个地方吗?不太确定是否有最佳实践!

问题2:教程还建议使用ServiceManager来实例化数据库模型以使用相同的实例。如果我有一个带有 5 个控制器的模块,每个控制器访问完全独立的表(例如每个 4 个表)怎么办?在我看来,它会在每个页面加载时冗余地初始化 16 个表(对于该模块中的其他控制器)。单个表初始化为页面加载增加了 55 毫秒。有没有解决的办法??我不确定如何根据教程初始化 tablegateway 的操作将配置移动到控制器的操作中?

4

1 回答 1

8

1)

您可以在应用程序的任何模块中使用任何模型,因此它们可以“共享”。例如,您使用 ServiceManager 来帮助您在项目中获取模型(和其他类)的实例。

服务管理器配置:

'factories' => array(
    'AuthService' => function($sm) {
        $auth = new \Zend\Authentication\AuthenticationService();

        return $auth;
    },
    'RoleMapper' => function($sm) {
        $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
        $mapper = new \Application\Mapper\RoleMapper;
        $mapper->setDbAdapter($dbAdapter);
        $mapper->setEntityPrototype(new \Application\Model\Role);
        $mapper->setHydrator(new \Application\Model\RoleHydrator);

        return $mapper;
    },
    'UserMapper' => function($sm) {
        $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
        $mapper = new \MyModule\Mapper\UserMapper;
        $mapper->setDbAdapter($dbAdapter);
        $mapper->setEntityPrototype(new \MyModule\Model\User);
        $mapper->setHydrator($sm->get('UserHydrator'));

        return $mapper;
    },
    ....

如您所见,您可以在其中定义来自多个模块的类。通常,您只需为每个模块定义一个单独的 ServiceManager 配置。

没有什么可以阻止您在应用程序模块中创建“UserMapper”实例,如下所示:

一些控制器:

$this->getServiceLocator()->get('UserMapper');
// Or even grab Zend libraries like this
$this->getServiceLocator()->get('AuthService');

ServiceManager 将允许您从有问题的任何其他模块中的任何模块中获取类的实例。

2)

在您请求之前,服务管理器实际上不会创建任何实例,因此没有您建议的开销。

从上面的示例中,在您第一次请求之前,实际上没有创建任何实例:

$this->getServiceLocator()->get('UserMapper'); // instance now created.

例如,如果您从不向服务管理器询问“RoleMapper”,则不会创建任何实例。

于 2013-02-26T08:48:32.357 回答