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