2012-12-22 114 views
27

如何在Zend Framework 2中配置(並使用)多個數據庫?目前我有我的global.php:在zf2中配置多個數據庫

return array(
    'db' => array(
     'driver'   => 'Pdo', 
     'dsn'   => 'mysql:dbname=my_db;host=localhost', 
     'driver_options' => array(
      PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'' 
     ), 
     'username' => 'user', 
     'password' => '******', 
    ), 
    'service_manager' => array(
     'factories' => array(
      'Zend\Db\Adapter\Adapter' => 'Zend\Db\Adapter\AdapterServiceFactory', 
     ), 
    ), 
); 

但我沒有看到添加第二個方法。

回答

50

如果你看一下了Zend \ DB \適配器\ AdapterServiceFactory,你會看到你的適配器配置點,只需一鍵'db'。這意味着它構建的適配器將始終使用此(唯一)配置密鑰。

我建議你創建自己的工廠,應該是這樣的:

namespace Your\Namespace; 

use Zend\ServiceManager\FactoryInterface; 
use Zend\ServiceManager\ServiceLocatorInterface; 
use Zend\Db\Adapter\Adapter; 

class MyAdapterFactory implements FactoryInterface 
{ 

    protected $configKey; 

    public function __construct($key) 
    { 
     $this->configKey = $key; 
    } 

    public function createService(ServiceLocatorInterface $serviceLocator) 
    { 
     $config = $serviceLocator->get('Config'); 
     return new Adapter($config[$this->configKey]); 
    } 
} 

在你的主模塊(或任何其他一個),添加以下到Module.php文件中聲明的適配器工廠到了Zend服務經理:

use Your\Namespace\MyAdapterFactory; 
use Zend\ModuleManager\Feature\ServiceProviderInterface; 

class Module implements ServiceProviderInterface{ 

//Previous code 

public function getServiceConfig() 
{ 
    return array(
     'factories' => array(
      'myadapter1'  => new MyAdapterFactory('dbconfigkey1'), 
      'myadapter2'  => new MyAdapterFactory('dbconfigkey2'), 
      ), 
     ); 

} 

//... 

全局配置現在應該是這樣的:

return array(
'dbconfigkey1' => array(
    'driver'   => 'Pdo', 
    'dsn'   => 'mysql:dbname=my_db;host=localhost', 
    'driver_options' => array(
     PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'' 
    ), 
    'username' => 'user', 
    'password' => '******', 
), 

'dbconfigkey2' => array(
    'driver'   => 'Pdo', 
    'dsn'   => 'mysql:dbname=my_db2;host=localhost', 
    'driver_options' => array(
     PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'' 
    ), 
    'username' => 'user', 
    'password' => '******', 
), 

); 

使用則需要使用服務管理器來調用它們適配器:

​​

截至目前版本2.2

一個抽象的服務廠是ZF2 Zend的\ DB模塊的一部分。這是可能的「適配器」子鍵下添加倍數配置鍵:

'db'=> array(
    'adapters'=>array(
     'adapter' => array(
      'driver'   => 'Pdo', 
      'dsn'   => 'mysql:dbname=test;host=localhost', 
      'username' => 'readCredential', 
      'password' => '****' 
     ), 
     'adapter2' => array(
      'driver'   => 'Pdo', 
      'dsn'   => 'mysql:dbname=test;host=localhost', 
      'username' => 'rwCredential', 
      'password' => '****' 
     ), 
    ) 
), 

然而,AbstractServiceFactory需要「手動」添加也沒那麼默認:

'service_manager' => array(
    'abstract_factories' => array(
      'Zend\Db\Adapter\AdapterAbstractServiceFactory', 
    ) 
), 

適配器是可訪問的如先前:

$adapter1=$serviceManager->get('adapter'); 
$adapter2=$serviceManager->get('adapter2'); 

從性能的角度來看,這第二個方法是較好的:一個對象將被(抽象工廠)實例化以(潛在)穿心蓮e不同的適配器。而在以前的方法中,每個配置創建一個對象。

+0

出現這種策略在2.1改變了嗎? – Saeven

+0

快速查看Zend \ Db \ Adapter \ AdapterServiceFactory後,我不這麼認爲。 – yechabbi

+8

不錯2.2信息,謝謝。 – Xunnamius

3

我找到了更好的交代上https://samsonasik.wordpress.com/2013/07/27/zend-framework-2-multiple-named-db-adapter-instances-using-adapters-subkey/

的Zend Framework 2.2自帶abstract_factories Zend\Db\Adapter\AdapterAbstractServiceFactory,使我們能夠配置多個命名DB適配器實例。這是一步一步做到這一點:

  1. 註冊Zend\Db\Adapter\AdapterAbstractServiceFactory在「abstract_factories」下「service_manager」鍵類型。

    //config/autoload/global.php // ....配置/自動加載/全局的一部分。PHP 'service_manager'=>數組( 'abstract_factories'=>數組( '的Zend \ DB \適配器\ AdapterAbstractServiceFactory', ) )

  2. 配置 '適配器' 下,在 'DB' 鍵子項config/autoload/global.php

//config/autoload/global.php // ...的配置的一部分和/自動加載/ global.php

'db' => array(
    'adapters' => array(

     'db1' => array(
      'driver'   => 'Pdo', 
      'dsn'    => 'mysql:dbname=zf2_staging;host=localhost', 
      'driver_options' => array(
       PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'' 
      ), 
     ), 

     'db2' => array(
      'driver'   => 'Pdo', 
      'dsn'    => 'mysql:dbname=zf2_test;host=localhost', 
      'driver_options' => array(
       PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'' 
      ), 
     ), 
    ), 
), 
  • 配置 '適配器' 下 '分貝' 鍵子項在config/autoload/local.php
  • //config/autoload/local.php

    return array(
        'db' => array(
         'adapters' => array(
          'db1' => array(
           'username' => 'root', 
           'password' => '', 
          ), 
          'db2' => array(
           'username' => 'other_user', 
           'password' => 'other_user_passwd', 
          ), 
         ), 
        ), 
    ); 
    
    使用 'DB1' 或 'DB2' 從的ServiceManager

    DB適配器
  • 呼叫轉接

    $ SM-> GET( 'DB1');

    $ sm-> get('db2');

  • 如果你需要得到$sm->get(‘Zend\Db\Adapter\Adapter’)作爲主適配器,「DB1」和「DB2」其他適配器特定的目的,那麼你需要直接在數據庫定義主適配器,所以config/autoload/global.php配置會像以下內容:

    //config/autoload/global.php

    return array(
        'db' => array(
         //this is for primary adapter.... 
         'driver'   => 'Pdo', 
         'dsn'    => 'mysql:dbname=zf21_learn;host=localhost', 
         'driver_options' => array(
          PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'' 
         ), 
    
         //other adapter when it needed... 
         'adapters' => array(
    
          'db1' => array(
           'driver'   => 'Pdo', 
           'dsn'    => 'mysql:dbname=zf2_staging;host=localhost', 
           'driver_options' => array(
            PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'' 
           ), 
          ), 
          'db2' => array(
           'driver'   => 'Pdo', 
           'dsn'    => 'mysql:dbname=zf2_test;host=localhost', 
           'driver_options' => array(
            PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'' 
           ), 
          ), 
    
         ), 
        ), 
        'service_manager' => array(
         // for primary db adapter that called 
         // by $sm->get('Zend\Db\Adapter\Adapter') 
         'factories' => array(
          'Zend\Db\Adapter\Adapter' 
            => 'Zend\Db\Adapter\AdapterServiceFactory', 
         ), 
         // to allow other adapter to be called by 
         // $sm->get('db1') or $sm->get('db2') based on the adapters config. 
         'abstract_factories' => array(
          'Zend\Db\Adapter\AdapterAbstractServiceFactory', 
         ), 
        ), 
    ); 
    

    config/autoload/global.local.php應該像下面也配置:

    //config/autoload/local.php

    return array(
        'db' => array(
         // for primary db adapter that called 
         // by $sm->get('Zend\Db\Adapter\Adapter') 
         'username' => 'root', 
         'password' => '', 
    
         // to allow other adapter to be called by 
         // $sm->get('db1') or $sm->get('db2') based on the adapters config. 
         'adapters' => array(
          'db1' => array(
           'username' => 'root', 
           'password' => '', 
          ), 
          'db2' => array(
           'username' => 'other_user', 
           'password' => 'other_user_passwd', 
          ), 
         ), 
        ), 
    );