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

Zend Framework 2 : Reset HeadTitle Position from View

Posted in Teknologi, Tutorial PHP, Zend Framework 2 by samsonasik on July 14, 2013

zf2-zendframework2Sometime, we need to reset position of title that default we can look at ZendSkeletonApplication like “My Album – ZF2 Skeleton Application” to something like “ZF2 Skeleton Application – My Album”.
We CAN NOT do this from view :

$this->headTitle($title, 'PREPEND');
//OR
$this->headTitle($title, 'APPEND');

because of the layout rendered after view rendered, so we need to pass a value from view to layout via placeholder. So after set a title at view, we need to pass a value via placeholder view helper.

// module/Album/view/album/album/index.phtml:
$title = 'My albums';
$this->headTitle($title);
$this->placeholder('titleType')->set('PREPEND');

so we can set the title type at layout like the following :

// module/Application/view/layout/layout.phtml:
echo $this->headTitle('ZF2 Skeleton Application', 
        $this->placeholder('titleType', 'APPEND'))
          ->setSeparator(' - ')->setAutoEscape(false);

$this->placeholder(‘titleType’, ‘APPEND’) that passed at 2nd parameter of headTitle() means that if titleType already set, so get from the already data, if no, set to ‘APPEND’ as default value.

When situation need to remove layout title ( parameter is ‘SET’), and use the view title, we need to make a conditional like this :

// module/Application/view/layout/layout.phtml:
if ($this->placeholder('titleType', 'APPEND') == 'SET') { 
    echo $this->headTitle()->setAutoEscape(false);
} else {
   echo $this->headTitle('ZF2 Skeleton Application', 
          $this->placeholder('titleType', 'APPEND'))
             ->setSeparator(' - ')->setAutoEscape(false);
}

That’s it 😉

references:
1. http://stackoverflow.com/questions/13949809/zend-framework-2-make-content-page-variable-accessable-in-layout-phtml
2. http://zf2.readthedocs.org/en/latest/modules/zend.view.helpers.placeholder.html#zend-view-helpers-initial-placeholder