使用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
我已经在application / configs中的“application.ini”中提到了数据库连接。我阅读了 here 关于模块特定的配置并尝试了它。
我从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"
.....
但是当我在模块的控制器中访问数据库时,我收到错误消息“找不到适配器......”请帮忙......
答案 0 :(得分: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);
}
在我的案例中,每个连接都在一个单独的.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
一旦你设置了这样的多个数据库,在创建模型时(在你想要的任何模块中),你可以告诉ZF你想要使用的数据库:
protected function _setupDatabaseAdapter() {
$this->_db = Zend_Registry::get('my_db1');
}
这将是您的默认适配器。如果您需要在同一查询中使用两个数据库,请使用以下命令启动模型的功能:
public function myAwesomeSqlQuery () {
$db1 = $this->getAdapter()->getConfig(); //default adapter
$db2 = Zend_Registry::get('my_db2')->getConfig(); //additional adapter
现在,您可以使用这两种数据库编写查询:
$sql = $this
->select()
->setIntegrityCheck(false)
->from(array('col1' => $db1['dbname'].'.some_column'))
->join(array('col2' => $db2['dbname'].'.some_other_column')),'col1.id = col2.id')
;
正如我在评论中建议的那样,您也可以使用特定于模块的bootstraps。结构将是这样的:
/application/
-- /modules/
-- /v1/
-- /controllers/
-- /views/
-- /Bootstrap.php
-- /v2/
-- /controllers/
-- /views/
-- /Bootstrap.php
模块特定的bootstrap与任何其他引导程序非常相似,但它们会影响所讨论的模块。类名通常以模块名称为前缀,例如:
<?php
class V1_Bootstrap extends Zend_Application_Bootstrap_Bootstrap {
...
}
我通常尽量不使用模块特定的bootstrap,因为它们都是针对每个请求启动的(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);
}
这就是它。我希望它有所帮助。
答案 1 :(得分: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...
然后它在下载中声明了一个db资源作为示例。只需将其更改为多数据库资源即可。在application.ini中声明应用程序所需的db资源,以及各自module.ini文件中任何特定模块所需的任何其他db资源。这很简单。这就是你需要做的。一旦你理解了My_App背后的逻辑,你会发现它非常强大。
答案 2 :(得分:1)
osebboy的解决方案未配置为具有除.ini之外的配置文件。你有application.xml。根据osebboy的解决方案,似乎初始设置不正确。
我建议您从他的github下载源代码并以此方式设置它。还阅读他的博客文章。