настроить несколько баз данных в 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', ), ), ); 

Но я не вижу способа добавить второй.

Если вы посмотрите на Zend \ Db \ Adapter \ 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 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

Завод абстрактной службы теперь является частью модуля 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'); 

С точки зрения эффективности этот второй подход лучше: один объект будет создан (абстрактный завод), чтобы (потенциально) создать различные адаптеры. Если в предыдущем подходе был создан один объект для каждой конфигурации.

Я нашел гораздо лучшее объяснение на 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 по Zend\Db\Adapter\AdapterAbstractServiceFactory 'abstract_factories' под ключом 'service_manager'.

    //config/autoload/global.php // …. часть config / autoload / global.php 'service_manager' => array ('abstract_factories' => array ('Zend \ Db \ Adapter \ AdapterAbstractServiceFactory',), ),

  2. Настроить подраздел «адаптеры» под ключом «db» в config/autoload/global.php

//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. Настроить подраздел «адаптеры» под ключом «db» в 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', ), ), ), ); 
  1. Адаптер вызова с использованием «db1» или «db2» в качестве адаптера db из ServiceManager

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