1
votes

i am using a modular architecture with Zend framework, and i want to use the module specific database configuration such that each module's model employs its own database configuration.

This is my sample application architecture:

  • application
    • modules
      • admin
        • controllers
        • models
          • DbTable
            • Users.php
        • views
        • configs
          • module.ini
    • configs
      • application.ini

From the above architecture, i have the module "admin" and i have specified its database configuration in admin/configs/module.ini like:

resources.db.adapter = "pdo_mysql" 
resources.db.params.host = "localhost" 
resources.db.params.username = "*****" 
resources.db.params.password = "*****" 
resources.db.params.dbname = "********"

Now I want to use this configuration in the models of "admin" module.

FYI, Iam instantiating the model in the "admin" module's controller like:

$admin = new Admin_Models_DbTable_Users();
$admin_users = $admin->fetchUsers();

And in the "admin" module's model, i am executing the queries like:

public function fetchUsers()
{
$sql = "select * from users";
return $this->getAdapter()->fetchAll($sql, array(), Zend_Db::FETCH_OBJ);
}

How can i load the database configuration in admin/configs/module.ini in my "admin" module's database adapter such that it uses that configuration? Do i need to use Zend Registry or set any options in admin module's bootstrap file ?

3

3 Answers

3
votes

You should use multidb resource plugin. In short, in you application.ini you should setup all your databases:

resources.multidb.employees.adapter = PDO_MYSQL
resources.multidb.employees.host = localhost
resources.multidb.employees.username = zend
resources.multidb.employees.password = zend
resources.multidb.employees.dbname = zend
resources.multidb.employees.default = true

resources.multidb.employees1.adapter = "PDO_SQLITE"
resources.multidb.employees1.dbname = APPLICATION_PATH "/../data/db/employeesdb.db"

Then in you Bootstrap.php you should save them into registry:

public function run()
{
    $resource = $this->getPluginResource('multidb');
    Zend_Registry::set('news', $resource->getDb('employees1'));
    Zend_Registry::set('employees', $resource->getDb('employees'));

    parent::run();
}

And at last in your db model class you should write:

  /**
    * Db name.
    *
    * @var string
    */
   protected $_use_adapter = 'employees1';

and (this part can be put to some abstract class which extends Zend_Db_Table_Abstract and will be parent for all your db models classes):

   public function __construct($config = null)
   {
       if(isset($this->_use_adapter)){
           $config = $this->_use_adapter;
       }
       return parent::__construct($config);
   }
2
votes

i am following a different approach, as suggested by one of my friends:

In the module's bootstrap file, i am setting the module's db adapter into the Registry, and in the module's model file, i am getting the module's db adapter from the registry using a custom method: getAdapter()

Code in ....application/modules/admin/Bootstrap.php

protected function _initAutoload()
    {       
        $configuration = new Zend_Config_Ini(
                APPLICATION_PATH . '/modules/admin/configs/module.ini', 
                'production'
                );

        $params = $configuration->resources->db->params->toArray();
        $DB = new Zend_Db_Adapter_Pdo_Mysql($params);

        Zend_Registry::set('DB',$DB);       

    }

Code in ...application/modules/admin/DbTable/Users.php

public function getAdapter()
    {   
        $registry   = Zend_Registry::getInstance();     
        return $registry['DB']; 
    }

So now the $this->getAdapter() in admin module's fetchUsers() method will have the db adapter of "admin" module. :)

1
votes

FYI: my friend also wanted to do this. He set a default adapter in the application.ini. Then in each zend_db model where he wanted to use another database, he changed the schema configuration. He said it was the easiest. Then his db model already had the authentication and host, and he just overwrote the database and table. Definitely consider this option; sorry I don't have any links or examples.