ZF2配置注入还是NOT? [英] ZF2 Configuration Injection Or NOT?

查看:141
本文介绍了ZF2配置注入还是NOT?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



或者,我可能从Application \Model\DBInterface获取配置



如果上述两种情况都不可能,那么我可以通过读取一个ini文件来获取db详细信息并实例化我的db



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



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

解决方案

好吧,所以@Ocramius只是让我知道我与初始化程序的误解,并帮助我有点理解它。所以这里是一个可能工作的解决方案,你的问题。我对您的问题的理解是:



如何为实现DbInterface的所有模型获取DbAdapter集。这是您的方式:






步骤1:创建<$ c $对于所有实现 DbInterface 的类,c> invokables 。为默认 Zend\Db\Adapter\Adapter 创建一个工厂,然后创建一个 initializer for DbInterface



Module.php getServiceConfig()

  '=> 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 \Adapter\Adapter 正在使用顶级配置数组键'db'自动注入dbParams






步骤2:创建实现您的界面的类



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

 命名空间Application\Model; 

class One实现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;
}

//这里有更多的业务逻辑或数据
}






步骤3:从您的控制器使用ServiceLocator访问这些类



SomeController.php someAction()

  $ dbOne = $ this-> getServiceLocator() - > get('application-model-one'); 
$ dbTwo = $ this-> getServiceLocator() - > get('application-model-two');
//适配器将自动注入

当访问 invokable 从ServiceManager中调用初始化程序。然后,初始化程序将自动调用 Zend\Db\Adapter\Adapter ,它依次从配置键'db' .zend.com / manual / 2.0 / en / user-guide / database-and-models.html#using-servicemanager-to-configure-the-table-gateway-and-inject-into-the-albumtablerel = nofollow>教程应用程序以及
的博客 samsonasik:ServiceManager Cheat-Sheet


I've googled a lot and read as much as I can on the subject but I cannot find a direct answer to my question anywhere including here. My ZF2 application consists of roughly 7 different modules. 5 of the modules will need access to the same database configuration. The application itself has a database with roughly 124 different tables. So the idea here is to find the proper solution to write the least amount of code considering the setup.

What I'm trying to do is create a specific class to interface with the DB. Where the business logic is kept in the Module and note the controllers to keep everything more abstract and easier to maintain. By that I mean controller X should be able to create a new instance of for instance (Application\Model\DBInterface) and use the models functions to do inserts deletes updates joins selects and so forth. The reason I would like to do it this way is so that all modules installed can use the same interface without having to write endless DI statements everywhere. So what I will need is an example of how I can get the configuration for the DB (currently inside module.config.php + local.php(username / pw)) to be passed to the Application\Model\DBInterface dbConfig variable, and perhaps even an instance of the dbAdapter initialized from config if possible.

Alternatively I could potentially grab the configuration from the Application\Model\DBInterface if such a way exists.

If neither of the above is possible then I can always go back to the old way of doing things by reading an ini file for the db details and instantiating my db adapter that way.

Please keep in mind that I won't be injecting anything in the controllers as the controllers just use $db = new \Application\Model\DBInterface() so injecting into the controllers doesn't make much sense at all.

Is there a better way to do this / optimized / am I doing it completely wrong? Anyone able to share some details please. I've spent way too much time on this already and definitely need help.

解决方案

Okay, so @Ocramius did just let me know what my misconception with the initializers was and helped me out a bit in understanding it. So here is a probably working solution to your Problem. My understanding about your problem is:

"How to get a DbAdapter set for all your Models implementing a DbInterface". This is how you'd do it:


Step 1: Create invokables for all classes implementing the DbInterface. Create a factory for the default Zend\Db\Adapter\Adapter and then create an initializer for your 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'));
            }
        },
    )
)

The Zend\Db\Adapter\Adapter is using the top-level-configuration-array-key 'db' to automatically inject the dbParams


Step 2: Create your classes implementing your Interface

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
}


Step 3: Access those classes with the ServiceLocator from your Controllers

SomeController.php someAction()

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

When accessing the invokable from the ServiceManager the initializer will be called. The initializer then will automatically call the Zend\Db\Adapter\Adapter, which in turn get's the parameters from the configuration key 'db'


You may get more information from once the tutorial Application as well as the blog of samsonasik: ServiceManager Cheat-Sheet

这篇关于ZF2配置注入还是NOT?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆