Configuration ZF2配置注入与否?

Configuration ZF2配置注入与否?,configuration,dependency-injection,zend-framework2,Configuration,Dependency Injection,Zend Framework2,关于这个问题,我在谷歌上搜索了很多,读了很多书,但我在任何地方都找不到直接的答案,包括这里。我的ZF2应用程序由大约7个不同的模块组成。其中5个模块需要访问相同的数据库配置。应用程序本身有一个包含大约124个不同表的数据库。因此,这里的想法是找到合适的解决方案,在考虑设置的情况下编写最少的代码 我要做的是创建一个特定的类来与DB接口。业务逻辑保存在模块中,并注意控制器,以使所有内容更加抽象和易于维护。我的意思是,控制器X应该能够创建一个新的实例,例如(Application\Model\DBIn

关于这个问题,我在谷歌上搜索了很多,读了很多书,但我在任何地方都找不到直接的答案,包括这里。我的ZF2应用程序由大约7个不同的模块组成。其中5个模块需要访问相同的数据库配置。应用程序本身有一个包含大约124个不同表的数据库。因此,这里的想法是找到合适的解决方案,在考虑设置的情况下编写最少的代码

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

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

如果以上两种方法都不可行,那么我可以通过读取一个ini文件来获取db详细信息并以这种方式实例化我的db适配器,从而回到以前的做法

请记住,我不会在控制器中注入任何内容,因为控制器只使用$db=new\Application\Model\DBInterface(),所以注入控制器没有多大意义


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

好的,所以@Ocramius让我知道了我对
初始值设定项的误解,并帮助我理解了它。因此,这里有一个可能有效解决您的问题的方法。我对你的问题的理解是:

“如何为实现DbInterface的所有模型获取DbAdapter集”。这就是你要做的:


步骤1:为实现
DbInterface
的所有类创建
invokables
。为默认的
Zend\Db\Adapter\Adapter
创建
factory
,然后为
DbInterface
创建
初始值设定项

Module.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'));
            }
        },
    )
)
$dbOne = $this->getServiceLocator()->get('application-model-one');
$dbTwo = $this->getServiceLocator()->get('application-model-two');
// Adapter will automatically be injected
Zend\Db\Adapter\Adapter正在使用顶级配置数组键
'Db'
自动注入dbParams


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

应用程序\模型(一|二| 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:使用控制器中的ServiceLocator访问这些类

SomeController.php
someAction()

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'));
            }
        },
    )
)
$dbOne = $this->getServiceLocator()->get('application-model-one');
$dbTwo = $this->getServiceLocator()->get('application-model-two');
// Adapter will automatically be injected
从ServiceManager访问可调用的
时,将调用
初始值设定项。然后,初始值设定项将自动调用
Zend\Db\Adapter\Adapter
,然后从配置键
'Db'
获取参数


您可能会从once以及的博客获得更多信息

好的,@Ocramius确实让我知道了我对
初始值设定项的误解,并帮助我理解了它。因此,这里有一个可能有效解决您的问题的方法。我对你的问题的理解是:

“如何为实现DbInterface的所有模型获取DbAdapter集”。这就是你要做的:


步骤1:为实现
DbInterface
的所有类创建
invokables
。为默认的
Zend\Db\Adapter\Adapter
创建
factory
,然后为
DbInterface
创建
初始值设定项

Module.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'));
            }
        },
    )
)
$dbOne = $this->getServiceLocator()->get('application-model-one');
$dbTwo = $this->getServiceLocator()->get('application-model-two');
// Adapter will automatically be injected
Zend\Db\Adapter\Adapter正在使用顶级配置数组键
'Db'
自动注入dbParams


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

应用程序\模型(一|二| 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:使用控制器中的ServiceLocator访问这些类

SomeController.php
someAction()

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'));
            }
        },
    )
)
$dbOne = $this->getServiceLocator()->get('application-model-one');
$dbTwo = $this->getServiceLocator()->get('application-model-two');
// Adapter will automatically be injected
从ServiceManager访问可调用的
时,将调用
初始值设定项。然后,初始值设定项将自动调用
Zend\Db\Adapter\Adapter
,然后从配置键
'Db'
获取参数


您可能会从once以及的博客获得更多信息

设置DI后,我建议注入所有服务。(并不是所有的东西都是服务,但DB访问肯定是!再说一次,我只在静态类型的环境中使用DI,所以我不需要担心使用令人讨厌的“服务定位器模式”。)尽管这是个问题,但如何设置DI?我看过无数关于注入控制器的文章,这也意味着必须向处理124个不同表的每个控制器添加di。现在使用di似乎不是一个非常可扩展的解决方案,除非我完全误解了我不知道PHP中的di是如何工作的,但是如果做得好,它应该比使用
new
s更简单。一旦它在任何地方使用,添加到任何特定服务的成本应该是微不足道的。可能是b