2011-03-04 43 views
11

iam使用zend框架構建REST Web服務,我使用模塊來分離我的api版本。zend模塊特定配置問題

現在,我想爲我的每個模塊(v1和v2)都有一個單獨的配置文件,主要用於指定單獨的數據庫連接。

我有這樣的目錄結構:

- application 
     - modules 
      - v1 
        - controllers 
        - models 
        - views 
        - configs 
        - module.ini   
      - v2 
        - controllers 
        - models 
        - views 
        - configs 
        - module.ini 
     - configs 
      - application.xml 
- library 

我已經在我的「的application.ini」裏面提到的應用/ CONFIGS數據庫連接。我讀了here關於模塊特定的配置並嘗試過。

我刪除從這些的application.ini數據庫PARAMS並把它放在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

需要更多的信息 - 在這行你的錯誤?這是一個PHP致命錯誤? – emaillenin 2011-03-04 12:43:34

+0

我認爲這只是一個正常的錯誤信息。但錯誤發生後執行停止。 – 2011-03-04 13:05:12

+0

您可以在/public/.htaccess文件中添加以下內容: 'SetEnv APPLICATION_ENV「development」' 然後告訴我們錯誤的詳細信息。 – Perfection 2011-03-04 15:02:21

回答

2

解決方案(程序my_app)你指的是你的問題並不需要對模塊特定的數據庫連接任何額外的配置,或任何其他特定模塊的配置(除了路線)。所有你需要做的是中的application.ini爲DB1聲明MultiDb資源。然後,您可以將請求的模塊各自的module.ini中的任何模塊特定數據庫資源聲明爲db2,db3,db4 ...等等...您不需要任何其他配置。我在github的下載文件中放置了一個例子。不要不尊重上面「mingos」的響應,但My_App中不需要任何附加代碼。

下面是下載(的application.ini)採取的確切verbage:

...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... 

然後,它聲明瞭一個數據庫資源作爲在下載的例子。只需將其更改爲多個數據庫資源即可。在application.ini中聲明應用程序範圍所需的數據庫資源,以及任何特定模塊在其各自的module.ini文件中所需的任何其他數據庫資源。這很簡單。這就是你需要做的。一旦你理解了My_App背後的邏輯,你會發現它非常強大。

+0

感謝您的親切的回答osebboy。它是你的偉大。你能否提到我需要在我的應用程序中編寫的行。ini聲明一個MultiDb資源? – 2011-03-21 05:48:51

+1

#resources.multidb.db1.adapter =「pdo_mysql」 #resources.multidb.db1.host =「localhost」 #resources.multidb.db1.username =「webuser」 #resources.multidb.db1.password =「 XXXX「 #resources.multidb.db1.dbname =」db1「 以上是multiDb資源的初始聲明。你可以在application.ini中聲明。由於它是在application.ini中聲明的,所有模塊都可以使用它。現在,如果您需要特定模塊中的任何其他Db資源,那麼您可以在其各自的module.ini中將該資源聲明​​爲db2,db3 ... – osebboy 2011-03-21 22:52:04

+0

這樣,您可以擁有應用程序範圍內的db資源和模塊特定的db資源。不需要代碼。請記住,My_App創建完全隔離的模塊。我建議你嘗試理解My_App背後的邏輯。 – osebboy 2011-03-21 23:00:55

1

osebboy的解決方案未配置爲具有.ini以外的配置文件。你有application.xml。這看起來像最初的設置是不正確的,取決於osebboy的解決方案。

我建議你從他的github下載源代碼並設置它。還請閱讀他的博客文章。

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') 
; 

正如我建議在評論中,您也可以使用模塊特定的引導程序。該結構將是這樣的:

/application/ 
    -- /modules/ 
    -- /v1/ 
     -- /controllers/ 
     -- /views/ 
     -- /Bootstrap.php 
    -- /v2/ 
     -- /controllers/ 
     -- /views/ 
     -- /Bootstrap.php 

與特定模塊白手起家構造很像其他任何引導,但卻會影響有問題的模塊。類名通常以模塊名稱作爲前綴,例如,:

<?php 
class V1_Bootstrap extends Zend_Application_Bootstrap_Bootstrap { 
    ... 
} 

我一般儘量不使用特定的模塊,白手起家,因爲它們都與每個請求啓動(Zend框架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); 
    } 

這幾乎是它。我希望它有幫助。

+2

+1和另一個如果我能! _非常好的答案! – Kyle 2011-03-07 11:57:53

+0

Mingos,我想試試您的解決方案,但我很困惑與模塊的模型部分...你可以張貼到模型,以及如何從模型或控制器 – 2011-03-12 12:14:18

+0

查詢這一切都沒有在回答相關的代碼。你有什麼問題,具體是? – mingos 2011-03-12 14:05:27