Zend Framework 2 : multiple named DB adapter instances using ‘adapters’ subkey
Zend Framework 2.2 comes with abstract_factories Zend\Db\Adapter\AdapterAbstractServiceFactory that allow us to configure multiple named DB adapter instances. This is step by step to do it :
1. Register Zend\Db\Adapter\AdapterAbstractServiceFactory at ‘abstract_factories’ type under ‘service_manager’ key.
//config/autoload/global.php //.... part of config/autoload/global.php 'service_manager' => array( 'abstract_factories' => array( 'Zend\Db\Adapter\AdapterAbstractServiceFactory', ), ),
2. Configure ‘adapters’ subkey under ‘db’ key at config/autoload/global.php
//config/autoload/global.php //.... part of 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\'' ), ), ), ),
3. Configure ‘adapters’ subkey under ‘db’ key at 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', ), ), ), );
3. Call adapter using ‘db1’ or ‘db2’ as db adapter from ServiceManager
$sm->get('db1'); //OR $sm->get('db2');
If you need to get $sm->get(‘Zend\Db\Adapter\Adapter’) as primary adapter, ‘db1’ and ‘db2’ as other adapter for specific purpose, then you need to define primary adapter directly under db, so the configuration of config/autoload/global.php will be like the following :
//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', ), ), );
The config/autoload/global.local.php should be configured too like the following :
//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', ), ), ), );
return array(
‘db’ => array(
‘adapters’ => array(
‘db1’ => array(
‘username’ => ‘root’,
‘password’ => ”,
),
‘db1’ => array(
‘username’ => ‘other_user’,
‘password’ => ‘other_user_passwd’,
),
),
),
);
you have a error db1, db2???
No
typo error in config/autoload/local.php, second db1 should be db2?
fixed, thank you 😀
Oops, fixed. thank you 😉
[…] multiple named DB adapter instances using ‘adapters’ subkey […]
aslm sdr samsonasik, sy baru saja kirim email. coba cek.
hey………………
i m not under stand
how can i set the $sm->get(‘db1′); $sm->get(;db2′);
its not woking
so help me
how can i set this method ??
$sm I write represent the ServiceManager, read https://samsonasik.wordpress.com/2013/01/02/zend-framework-2-cheat-sheet-service-manager/ for how to use it.
hey….
thanks for help.. 🙂
$sm->get(‘db1’);
//OR
$sm->get(‘db2’);
if i use only one
then data can be store on multiple database ??
@samsonasik Thanks for this code.
you’re welcome 😉
How do I send the non-default adapter(db2) to my controller and model through getServiceConfig() and how do I access the same in the controller and model? Please help, I am quite new to Zend.
please read and understand https://samsonasik.wordpress.com/2013/01/02/zend-framework-2-cheat-sheet-service-manager/
Thanks for the reply. I still have doubts. I have a default database: db. But in some modules I need to pass the non-default database: user_common to the model. How do I do it from the getServiceConfig() and get the same in the model?
use abstract_factories, read again https://samsonasik.wordpress.com/2013/01/02/zend-framework-2-cheat-sheet-service-manager/ and understand that.
mas Abdul Malik, kalau berkenan, saya minta tolong konsultasi, saya punya aplikasi lama dengan zend framework 1.10 yang jalan dengan single koneksi ke oracle,
pas saya ubah ke multidb error “tns 12154 ORA-12154: TNS:could not resolve the connect identifier specified *”
sudah saya lakukan beberapa petunjuk dari internet masih begitu, padahal koneksi oracle dari yang single koneksi ga masalah, sebelumnya terima kasih
berikut code nya
Bootstrap.php
code lama
protected function _initDb()
{
$config = new Zend_Config_Ini(APPLICATION_PATH . ‘/application.ini’, APPLICATION_ENV);
$db = Zend_Db::factory($config->resources->db->adapter, array(
//’host’ => $config->resources->db->params->host,
‘username’ => $config->resources->db->params->username,
‘password’ => $config->resources->db->params->password,
‘dbname’ => $config->resources->db->params->host . ‘/’ . $config->resources->db->params->dbname,
‘profiler’ => $config->resources->db->params->profiler,
‘options’ => array(Zend_Db::AUTO_QUOTE_IDENTIFIERS => false)
));
Zend_Registry::set(‘db’, $db);
Zend_Db_Table::setDefaultAdapter($db);
}
code baru
protected function _initDb()
{
$this->bootstrap(‘multidb’);
$resource = $this->getPluginResource(‘multidb’);
$resource->init();
$db = $resource->getDb(‘db1’);
Zend_Registry::set(‘db’, $resource->getDb(‘db1’));
Zend_Db_Table::setDefaultAdapter($db);
}
application.ini
code lama
; database
resources.db.adapter = “oracle”
resources.db.params.host = “localhost”
resources.db.params.username = “PIMS”
resources.db.params.password = “PIMS”
resources.db.params.dbname = “XE”
resources.db.isDefaultTableAdapter = true
; — profiler
resources.db.params.profiler.enabled = false
resources.db.params.profiler.class = “Zend_Db_Profiler_Firebug”
code baru
; database
resources.multidb.db1.adapter = “oracle”
resources.multidb.db1.host = “localhost”
resources.multidb.db1.username = “PIMS”
resources.multidb.db1.password = “PIMS”
resources.multidb.db1.dbname = “XE”
resources.multidb.db1.default = true
; — profiler
resources.multidb.db1.profiler.enabled = false
resources.multidb.db1.profiler.class = “Zend_Db_Profiler_Firebug”
udah lama ga pakai zf1 sih, mungkin mas bisa coba tanya di mailing list nya http://framework.zend.com/archives/
Hello
If you need to get $sm->get(‘Zend\Db\Adapter\Adapter’) as primary adapter, ‘db1’ and ‘db2’ as other adapter for specific purpose,
How call the adapter from my controller??
thanks
db adapter should be called inside mapper instead of controller, if you really need it, just call via getServiceLocator() :p
How can we configure multiple nosql dbs in one application. I have configured one db(MongoDB) in module.doctrine-mongo-odm.local.php. For Multiple Dbs, how can we set the db details?
Zend\Db is not Doctrine, this post is about Zend\Db