Настроить несколько баз данных в 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',
),
),
);
Но я не вижу способа добавить второй.
Ответы
Ответ 1
Если вы посмотрите на Zend\Db\Adapter\AdapterServiceFactory, вы увидите, что ваша конфигурация адаптера указывает только на один ключ 'db'
. Это означает, что адаптер, который он создает, всегда будет использовать этот (уникальный) ключ конфигурации.
Я рекомендую вам создать свой собственный factory, который будет выглядеть так:
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
Абстрактная служба 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');
С точки зрения эффективности этот второй подход лучше: один объект будет создан (абстрактный factory), чтобы (потенциально) создать различные адаптеры. Если в предыдущем подходе был создан один объект для каждой конфигурации.
Ответ 2
Я нашел гораздо лучшее объяснение 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-адаптеров. Это делается шаг за шагом:
-
Зарегистрируйте Zend\Db\Adapter\AdapterAbstractServiceFactory
в 'abstract_factories type под ключом service_manager.
//конфиг/автозагрузка/global.php
//.... часть config/autoload/global.php 'service_manager' = > массив ( 'abstract_factories' = > массив ( 'Zend\Db\адаптер\AdapterAbstractServiceFactory', ), ),
-
Настроить "поддиапазоны" под ключом "db" в config/autoload/global.php
//конфиг/автозагрузка/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\''
),
),
),
),
- Настроить "адаптеры" под ключом "db" в
config/autoload/local.php
//конфиг/автозагрузка/local.php
return array(
'db' => array(
'adapters' => array(
'db1' => array(
'username' => 'root',
'password' => '',
),
'db2' => array(
'username' => 'other_user',
'password' => 'other_user_passwd',
),
),
),
);
-
Адаптер вызовов с использованием 'db1 или' db2 в качестве адаптера db из ServiceManager
$SM- > Get ( 'DB1');
$SM- > Get ( 'db2');
Если вам нужно получить $sm->get(‘Zend\Db\Adapter\Adapter’)
в качестве основного адаптера, 'db1 и' db2 в качестве другого адаптера для определенной цели, тогда вам нужно определить первичный адаптер непосредственно под db, поэтому конфигурация config/autoload/global.php
будет выглядеть следующим образом:
//конфиг/автозагрузка/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
должен быть настроен так, как показано ниже:
//конфиг/автозагрузка/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',
),
),
),
);