Apr 262012
 

With the new modular infrastructure in Zend Framework 2, one of the most common questions will indoubitably be how to share a database connection across modules. Here’s a quick explanation of how to set up and share your database connection across multiple modules in a way that can even allow you to use a single connection between Zend\Db, Doctrine2, and possibly even other database libraries / ORMs.

To start, we’ll want to drop in a config file which defines the application-wide database connection that we’ll be using:

<?php
/**
 * ./config/autoload/database.local.php
 */
return array(
    'service_manager' => array(
        'factories' => array(
            'Zend\Db\Adapter\Adapter' => 'Zend\Db\Adapter\AdapterServiceFactory',
        ),
    ),
    'db' => array(
        'driver'         => 'pdo',
        'dsn'            => 'mysql:dbname=CHANGEME;host=localhost',
        'username'       => 'CHANGEME',
        'password'       => 'CHANGEME',
        'driver_options' => array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'"),
    ),
);

The idea is that each module should define it’s own DB adapter service manager alias. For example, in ZfcUser, we use the alias zfcuser_zend_db_adapter, which is aliased to Zend\Db\Adapter\Adapter by default. A module should only attempt to use its own DB adapter alias when injecting the adapter into the various classes that need it. The above config sets up Zend\Db\Adapter\Adapter as a valid Zend\Db adapter, so if modules are using that as the default target for their alias, things will “just work”. For more advanced cases, you can point each module’s database adapter alias to any configured DB adapter instance (alias) you’d like:

<?php
/**
 * ./config/autoload/database-connections.global.php
 */
return array(
    'service_manager' => array(
        'aliases' => array(
            'zfcuser_zend_db_adapter' => 'some_auth_specific_db',
        ),
    ),
);

(This is just an example. ZfcUser comes with a .dist config file which makes changing the DB adapter alias even easier.)

If you have third party database libraries, like Doctrine2 for example, you’ll also have the raw PDO connection available for injection, so that even Doctrine2 could share the same underlying database connection as Zend\Db in the same application. While it sounds a little clunky, this approach allows you to install modules which use Doctrine2 right along side modules that are using Zend\Db in a single application, all sharing one single PDO database connection. Since the release of the service manager stuff, I have not re-visited how to share the PDO connection resource across libraries (Zend\Db and Doctrine). I do intend to get to this eventually, but it is low on my priority list. If it’s something you’re looking for, let me know in the comments and it might motivate me to look into it again.

  12 Responses to “Sharing a database connection across modules in Zend Framework 2”

  1. Thanks for your tutorial.

    But can you send to me an demo to test it.

  2. Silly question, maybe, if a database connection is never consumed/used, are any of those db classes loaded or configured?

    The configurations are merged together, right? But that’s all, they’re just merged together, no object graph other than maybe Zend_Config or something like that which acts as a kind of container for the configuration. Objects are only created and configured if and only if required e.g. for the db, only if the database connection is actually needed?

    Not being familiar with DI leads to an impression of a huge object graph and needless inclusion of files that are never needed, but I don’t actually think that’s case, I at least hope.

    I think an understanding of the core is a must for zf2.

    • Generally speaking, only what is needed for a request is loaded. In cases where you have a complex controller that has large, conditional dependencies, you can set it up to lazily pull those from the DiC as-needed: $someDep = $this->getLocator()->get(‘mydependency’);

  3. I know you’ve been busy but is there a chance of getting an update to this so it works with Beta 4? It would be great to see how to properly setup the Database details and then how to tap into that resource so we can use it across all modules. I’d personally love to see how to make this work so I can do something like I did with ZF1 and use the DB Connection inside of what ZF1 called a Service Layer and return those results to the Controller so the View has the details.

  4. First of all, thanks for your tutorial.

    I’m fighting with ZF2 beta 4 trying to figure out the easiest and cleanest way to manage dual (redundant) database connections. ZF1 was quite straight forward but I must admit that I have a hard time with ZF2 and its new features. I see no issue using the new TableGateway together with redundancy. Am I wrong? Thanks for your advice

    • I’ll be updating this post for >= beta4 shortly.

      • That would be awesome… I’ve been fighting with myself trying to learn how to make this DB stuff work properly. Akrabat’s tutorial is great but it uses the Controller and I personally would rather use something like a Service Layer (ZF1 Style).

    • This post has now been updated for beta5!

  5. Am new to ZF2, how to configure different databases for different modules. Each module will have to access different database on same host. ‘db’ => array( ‘driver’ => ‘Pdo’, ‘dsn’ => ‘mysql:dbname=test;host=localhost’, ‘driver_options’ => array( PDO::MYSQL_ATTR_INIT_COMMAND => ‘SET NAMES \’UTF8\” ), ‘username’ => ‘root’, ‘password’ => ”, ), placed above code in module.config.php for each module with different DB name eg. ‘db1′, ‘db2′……

    thanks in advance

  6. Great, could get rid of my PHP 5.3 encoding problems by using driver_options! Thank you so much!

  7. I would like to share a db connection with Propel pretty bad. Any news on this Evan?

  8. Hi Evan im quite follower of your posts. Here’s my question how do i configure and use multiple database connections using Doctrine 2 and ZF2 with DoctrineORMModule? I already tried adding entries to the connection section on my global.php config file but how do i tell to the entity manager wich connection use at anytime?. Thnx, ^_^

 Leave a Reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre user="" computer="" color="" escaped="">