zend模块特定配置的问题

sha*_*nth 11 php zend-framework

我使用zend框架来构建REST Web服务,我使用模块来分离我的api版本.

现在,我想为每个模块(v1和v2)分别配置一个配置文件,主要用于指定单独的数据库连接.

我有一个像这样的目录结构:

- application
      - modules
            - v1
                  - controllers
                  - models
                  - views
                  - configs
                    - module.ini         
            - v2
                  - controllers
                  - models
                  - views  
                  - configs
                    - module.ini
      - configs
            - application.xml   
- library
Run Code Online (Sandbox Code Playgroud)

我已经在application/configs中的"application.ini"中提到了数据库连接.我在这里阅读有关模块特定的配置并尝试了它.

我从application.ini中删除了这些数据库参数并将其放在module.ini中:

[production]
resources.db.adapter = PDO_MYSQL
resources.db.params.host = 127.0.0.1
resources.db.params.username = myuser   
resources.db.params.password = mypwd
resources.db.params.dbname = my_db
resources.db.params.profiler.enabled = "true"
resources.db.params.profiler.class = "Zend_Db_Profiler_Firebug"
Run Code Online (Sandbox Code Playgroud)

.....

但是当我在模块的控制器中访问数据库时,我收到一条错误,上面写着"找不到适配器......" 请帮忙...

min*_*gos 6

在引导程序中,您可以设置数据库连接:

protected function _initDb () {
    $config['my_db1'] = new Zend_Config_Ini(APPLICATION_PATH . '/configs/my_db1.ini');
    $config['my_db2'] = new Zend_Config_Ini(APPLICATION_PATH . '/configs/my_db2.ini');

    $my_db1 = new Plugin_Replication($config['my_db1']->toArray());
    $my_db1->query("SET CHARACTER SET utf8;");

    $my_db2 = new Plugin_Replication($config['my_db2']->toArray());
    $my_db2->query("SET CHARACTER SET utf8;");

    Zend_Db_Table::setDefaultAdapter($dmy_db1);
    Zend_Registry::set('my_db1', $my_db1);
    Zend_Registry::set('my_db2', $my_db2);
}
Run Code Online (Sandbox Code Playgroud)

在我的案例中,每个连接都在一个单独的.ini文件中指定.我发现这非常直观有条理.数据库ini文件不需要resources.db.whatever名称.我是这样的:

[Master]
host = "xxx"
username = "xxx"
password = "xxx"
dbname = "xxx"
charset = utf8

[Slaves]
first.host = "xxx"
first.username = "xxx"
first.password = "xxx"
first.dbname = "xxx"
first.charset = utf8

second.host = "xxx"
second.username = "xxx"
second.password = "xxx"
second.dbname = "xxx"
second.charset = utf8
Run Code Online (Sandbox Code Playgroud)

一旦你设置了这样的多个数据库,在创建模型时(在你想要的任何模块中),你可以告诉ZF你想要使用的数据库:

protected function _setupDatabaseAdapter() {
    $this->_db = Zend_Registry::get('my_db1');
}
Run Code Online (Sandbox Code Playgroud)

这将是您的默认适配器.如果您需要在同一查询中使用两个数据库,请使用以下命令启动模型的功能:

public function myAwesomeSqlQuery () {
    $db1 = $this->getAdapter()->getConfig(); //default adapter
    $db2 = Zend_Registry::get('my_db2')->getConfig(); //additional adapter
Run Code Online (Sandbox Code Playgroud)

现在,您可以使用这两种数据库以这种方式编写查询:

$sql = $this
    ->select()
    ->setIntegrityCheck(false)
    ->from(array('col1' => $db1['dbname'].'.some_column'))
    ->join(array('col2' => $db2['dbname'].'.some_other_column')),'col1.id = col2.id')
;
Run Code Online (Sandbox Code Playgroud)

正如我在评论中建议的那样,您也可以使用特定于模块的bootstraps.结构将如下所示:

/application/
  -- /modules/
    -- /v1/
        -- /controllers/
        -- /views/
        -- /Bootstrap.php
    -- /v2/
        -- /controllers/
        -- /views/
        -- /Bootstrap.php
Run Code Online (Sandbox Code Playgroud)

模块特定的bootstrap与任何其他引导程序非常相似,但它们会影响相关模块.类名通常以模块名称为前缀,例如:

<?php
class V1_Bootstrap extends Zend_Application_Bootstrap_Bootstrap {
    ...
}
Run Code Online (Sandbox Code Playgroud)

我通常尽量不使用模块特定的bootstraps,因为它们都是随每个请求一起启动的(Zend Framework 2应该纠正这个),运行当前模块不需要的函数.无论如何,我在我的一个模块中找到了一个特定于模块的引导程序,其中包含以下内容:

class MyModule_Bootstrap extends Zend_Application_Bootstrap_Bootstrap {
    protected function _initLoggers () {
        $my_db1 = Zend_Registry::get('my_db1');
        $my_db2 = Zend_Registry::get('my_db2');
        $my_db1->setProfiler(new Zend_Db_Profiler_Firebug())->getProfiler()->setEnabled(true);
        $my_db2->setProfiler(new Zend_Db_Profiler_Firebug())->getProfiler()->setEnabled(true);

        $auth = Zend_Auth::getInstance();
        $columnMapping = array('priority' => 'priority' , 'message' => 'message' , 'timestamp' => 'timestamp' , 'username' => 'username');
        $logger = new Zend_Log(new Zend_Log_Writer_Db($my_db1, 'logs', $columnMapping));
        print_r($auth->getIdentity());
        if ($auth->hasIdentity())
            $logger->setEventItem('username', $auth->getIdentity()->username);
        Zend_Registry::set('logger', $logger);
    }
Run Code Online (Sandbox Code Playgroud)

这就是它.我希望它有所帮助.

  • 如果可以的话,+1和另一个!_Very_很好的答案! (2认同)

ose*_*boy 2

您在问题中引用的解决方案(My_App)不需要针对特定​​于模块的数据库连接进行任何额外配置,或任何其他特定于模块的配置(路由除外)。您所需要做的就是在 application.ini 中将 MultiDb 资源声明为 db1。然后,您可以在请求的模块各自的 module.ini 中将任何模块特定的数据库资源声明为 db2、db3、db4...等...您不需要任何额外的配置。我在 github 的下载文件中放置了一个示例。不要不尊重上面“mingos”的响应,但My_App中不需要任何额外的代码。

以下是从下载 (application.ini) 中获取的确切措辞:

...if this resource is declared here, then it
will be available to all modules. If different
db resources need to be used for different
modules then MultiDB resource can be
initiated. Example: A general db resource can be
defined here and a module specific db can be
declared in its corresponding module.ini.
The db resource declared in the module will not
be available to other modules but the db resource
in this application.ini will be available to all
modules...
Run Code Online (Sandbox Code Playgroud)

然后它声明单个数据库资源作为下载中的示例。只需将其更改为多数据库资源即可。在 application.ini 中声明应用程序范围所需的数据库资源,并在各自的 module.ini 文件中声明任何特定模块所需的任何其他数据库资源。这很简单。这就是您需要做的全部。一旦你理解了My_App背后的逻辑,你就会发现它非常强大。