web-dev-qa-db-ja.com

zf2で複数のデータベースを構成する

Zend Framework 2で複数のデータベースを構成(および使用)するにはどうすればよいですか?現在、これは私のglobal.phpにあります:

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

しかし、2つ目を追加する方法がわかりません。

28
tihe

Zend\Db\Adapter\AdapterServiceFactoryを見ると、アダプター構成が1つのキーのみを指していることがわかります'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 Service Managerにアダプターファクトリを宣言します。

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' => '******',
),

);

アダプターを使用するには、Service Managerを使用して呼び出す必要があります。

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

バージョン2.2以降

Abstract Service Factoryが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');

パフォーマンスの観点からは、この2番目のアプローチの方が優れています。1つのオブジェクトがインスタンス化され(抽象ファクトリ)、異なるアダプタが(潜在的に)作成されます。以前のアプローチでは、構成ごとに1つのオブジェクトが作成されました。

51
yechabbi

私は https://samsonasik.wordpress.com/2013/07/27/zend-framework-2-multiple-named-db-adapter-instances-using-adapters-subkey/ でより良い説明を見つけました=

Zend Framework 2.2には、複数の名前付きDBアダプターインスタンスを構成できるabstract_factories _Zend\Db\Adapter\AdapterAbstractServiceFactory_が付属しています。これはそれを行うためのステップバイステップです:

  1. 「service_manager」キーの下の「abstract_factories」タイプで_Zend\Db\Adapter\AdapterAbstractServiceFactory_を登録します。

    //config/autoload/global.php // .... config/autoload/global.phpの一部 'service_manager' => array( 'abstract_factories' => array( 'Zend\Db\Adapter\AdapterAbstractServiceFactory'、)、 )、

  2. _config/autoload/global.php_の「db」キーの下に「アダプター」サブキーを設定します

//config/autoload/global.php // .... config/autoload/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\''
            ),
        ),
    ),
),
_
  1. _config/autoload/local.php_の「db」キーの下に「アダプター」サブキーを設定します

//config/autoload/local.php

_return array(
    'db' => array(
        'adapters' => array(
            'db1' => array(
                'username' => 'root',
                'password' => '',
            ),
            'db2' => array(
                'username' => 'other_user',
                'password' => 'other_user_passwd',
            ),
        ),
    ),
);
_
  1. ServiceManagerから「db1」または「db2」をdbアダプタとして使用してアダプタを呼び出す

    $ sm-> get( 'db1');

    $ sm-> get( 'db2');

特定の目的で$sm->get(‘Zend\Db\Adapter\Adapter’)をプライマリアダプターとして取得し、 'db1'および 'db2'を他のアダプターとして取得する必要がある場合、プライマリアダプターをdbの直下で定義する必要があるため、_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',
            ),
        ),
    ),
);
_
3
Ritesh