2013-02-12 67 views
0

我已经GOOGLE了很多,并尽可能多地阅读主题,但我无法找到任何地方包括这里的任何问题的直接答案。我的ZF2应用程序由大约7个不同的模块组成。其中5个模块需要访问相同的数据库配置。应用程序本身有一个包含大约124个不同表的数据库。所以这里的想法是找到合适的解决方案来考虑设置来编写最少量的代码。ZF2配置注入或不?

我想要做的是创建一个特定的类来与数据库接口。业务逻辑保存在模块中,并注意控制器保持一切更抽象和更容易维护。我的意思是控制器X应该能够创建一个新的实例(Application \ Model \ DBInterface),并使用模型函数来执行插入删除更新连接选择等等。我想这样做的原因是,所有安装的模块都可以使用相同的接口,而无需在任何地方编写无穷无尽的DI语句。所以我需要的是一个例子,我可以如何获得DB的配置(目前在module.config.php + local.php(username/pw)中)传递给Application \ Model \ DBInterface dbConfig变量,以及如果可能的话,甚至可能还有一个从配置初始化的dbAdapter实例。

或者我可以从Application \ Model \ DBInterface获取配置,如果存在这种方式的话。

如果以上两种都不可行,那么我可以通过阅读ini文件获取数据库详细信息并以此方式实例化我的数据库适配器,从而可以始终回到旧的处理方式。

请注意,我不会在控制器中注入任何东西,因为控制器只是使用 $ db = new \ Application \ Model \ DBInterface()因此注入到控制器中并没有什么意义所有。

有没有更好的方法来做到这一点/优化/我是否完全错误?任何人都可以分享一些细节。我已经在这方面花了太多时间,并且绝对需要帮助。

+1

的博客一旦DI是设置,我建议注入*每个*服务。 (并非所有的服务都是服务,但数据库访问肯定是!再次,我只在静态类型的环境中使用DI,所以我不需要担心使用恶意的“服务定位器模式”。) – 2013-02-12 22:55:49

+0

如何设置这个DI虽然这是个问题?我已经看到无数关于注入到控制器的文章,这也意味着您必须将di添加到处理124个不同表的每个控制器中。现在看起来似乎不是一个非常可扩展的解决方案来使用DI,除非我完全误解了 – 2013-02-12 22:58:39

+0

我不知道DI在PHP中是如何工作的,但如果做得对,它应该比使用'new's在那个地方。一旦它在任何地方使用,添加到任何特定服务的成本应该是微不足道的。如果CRUD是可预测的,那么寻找发电机可能是值得的。 – 2013-02-12 22:59:23

回答

4

好的,@Ocramius确实让我知道我对initializers的误解是什么,并帮助我理解它。所以这里是解决你的问题的一个可能的解决方案。我对您的问题的理解是:

“如何为实现DbInterface的所有模型设置DbAdapter”。这是你会怎么做:


第1步:创建invokables为实现DbInterface所有类。默认Zend\Db\Adapter\Adapter创建factory,然后你DbInterface

模块创建initializer。PHP getServiceConfig()

return array(
    'invokables' => array(
     'application-model-one' => 'Application\Model\One', 
     'application-model-two' => 'Application\Model\Two' 
    ), 
    'factories' => array(
     'Zend\Db\Adapter\Adapter' => 'Zend\Db\Adapter\AdapterServiceFactory' 
    ), 
    'initializers' => array( 
     'DbInterfaceInitializer' => function($instance, $sm) { 
      if ($instance instanceof \Application\Model\DBInterface) { 
       $instance->setDbAdapter($sm->get('Zend\Db\Adapter\Adapter')); 
      } 
     }, 
    ) 
) 

的Zend \ DB \适配器\适配器使用顶级配置阵列密钥'db'自动注入dbParams


步骤2:创建您的类实现您的接口

Application \ Model(One | Two | N).php

namespace Application\Model; 

class One implements DbInterface, \Zend\Db\Adapter\AdapterAwareInterface 
{ 
    /** 
    * @var \Zend\Db\Adapter\Adapter $dbAdapter 
    */ 
    protected $dbAdapter; 

    public function setDbAdapter(\Zend\Db\Adapter\Adapter $dbAdapter) { 
     $this->dbAdapter = $dbAdapter; 
    } 

    public function getDbAdapter() { 
     return $this->dbAdapter; 
    } 

    // More of your business logic or data here 
} 

第3步:访问与服务定位这些课程从您的控制器

SomeController.php someAction()

$dbOne = $this->getServiceLocator()->get('application-model-one'); 
$dbTwo = $this->getServiceLocator()->get('application-model-two'); 
// Adapter will automatically be injected 

当从的ServiceManager访问invokableinitializer将被调用。在初始化之后就会自动调用Zend\Db\Adapter\Adapter,进而获取是从配置关键参数'db'


你可以从一次the tutorial Application获得更多的信息,以及对 samsonasik: ServiceManager Cheat-Sheet

+0

@Ocramius好吧;)在删除这个答案之前,你有没有时间在一两句话中解释初始值? – Sam 2013-02-13 08:47:38

+0

即使你的回答被拒绝了,我想这个问题已经给出了关于我在任何地方发现的一般问题的一些最好的信息。 @Ocramius,如果你可以提供更好的解决方案,请做...否则,我会很乐意测试Sam的解决方案,并给予他提供适当的功劳,以便提供一个可行的解决方案,即使这不是最佳实践似乎回答了问题。 – 2013-02-19 22:23:16

+0

@威尔实际上是我对这一个进行了降低投票,但我也没有注意到它被修改了。我删除了我的评论,以避免在未来的读者混淆和upvoting(我没有提供更好的解决方案,因为我个人讨厌初始化)。 – Ocramius 2013-02-19 22:26:48