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.