views:

344

answers:

2

Assuming you're hewing closely to the conventions of a ZendApplication, where should you be setting up a database handler for application developers to access?

I know how to setup a ZendDb adapter. What I want to know is, in the context of the Zend Framework, how should developers be instantiating their DB handlers so they don't have to worry about multiple instantiations across one request, supplying credentials each time, etc.

For example, when a developer is using Code Igniter and needs to run an arbitrary query, there's a database handler on the controller.

$this->db->query(....

What's the Zend equivalent of this convention? To be clear, I can think of half a dozen way to accomplish this using the tools that the Zend Framework provides. What I'm looking for is how Zend Framework, in the general case, wants you to do this.

+12  A: 

The idea is that your Bootstrap reads a config file and you declare config entries to describe the database adapter you want to create:

[bootstrap]
resources.db.adapter = Pdo_Mysql
resources.db.params.dbname = "mydatabase"
resources.db.params.username = "webuser"
resources.db.params.password = "XXXX"
resources.db.isDefaultTableAdapter = true

If you use the config keys following the right convention, this automatically signals the Bootstrap base class to create and initialize a Zend_Application_Resource_Db object, and stores it in the bootstrap resource registry.

Later in your Controller, you can access the resource registry. note: I've edited this code after testing it a bit more.

class SomeController extends Zend_Controller_Action
{
    public function init()
    {
        $bootstrap = $this->getInvokeArg("bootstrap");
        if ($bootstrap->hasPluginResource("db")) {
            $dbResource = $bootstrap->getPluginResource("db");
            $db = $dbResource->getDbAdapter();
        }
    }
}

Alternatively, you can write a custom init method in your Bootstrap class, to save an object in the default Zend_Registry:

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
  protected function _initDb()
  {
    if ($this->hasPluginResource("db")) {
      $dbResource = $this->getPluginResource("db");
      $db = $dbResource->getDbAdapter();
      Zend_Registry::set("db", $db);
    }
  }
}

Now you can access your db object in one step instead of three:

class SomeController extends Zend_Controller_Action
{
    public function init()
    {
        $db = Zend_Registry::get("db");
    }
}

Personally, I would use the second technique, because then I have to access the resource registry only once, in my bootstrap. In the first example I would have to copy the same block of code to all of my Controllers.

Bill Karwin
A: 

Thank you; this is one very helpful explanation, and it seems to work on my 1.9.7 installation except of this error when trying to access the registry again: Uncaught exception 'Zend_Exception' with message 'No entry is registered for key 'db''.

bob