Welcome to Abdul Malik Ikhsan's Blog

Zend Framework 2 : multiple named DB adapter instances using ‘adapters’ subkey

Posted in Zend Framework 2 by samsonasik on July 27, 2013

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

19 Responses

Subscribe to comments with RSS.

  1. ernesto quintero said, on July 29, 2013 at 2:48 am

    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???

  2. […] multiple named DB adapter instances using ‘adapters’ subkey […]

  3. mirzam said, on August 13, 2013 at 7:57 pm

    aslm sdr samsonasik, sy baru saja kirim email. coba cek.

  4. priyank said, on December 4, 2013 at 4:54 pm

    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 ??

  5. priyank said, on December 4, 2013 at 6:57 pm

    $sm->get(‘db1′);
    //OR
    $sm->get(‘db2′);

    if i use only one
    then data can be store on multiple database ??

  6. lukemx said, on February 12, 2014 at 7:39 pm

    @samsonasik Thanks for this code.

  7. Pd said, on April 15, 2014 at 1:40 am

    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.

  8. suryanto said, on March 31, 2015 at 6:13 pm

    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”


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 315 other followers

%d bloggers like this: