(This post is the second part of my previous post: Handling several PDO Database connections in Symfony2 through the Dependency Injection Container with PHP. You can read it here)
OK. We can handle PDOs connections inside a Symfony2 application, but what happens if we prefer DBAL. As we know DBAL is built over PDO and adds a set of “extra” features to our database connection. It’s something like PDO with steroids.
If we read the documentation, we will see how to use DBAL:
<?php
$config = new \Doctrine\DBAL\Configuration();
//..
$connectionParams = array(
'dbname' => 'mydb',
'user' => 'user',
'password' => 'secret',
'host' => 'localhost',
'driver' => 'pdo_mysql',
);
$conn = DriverManager::getConnection($connectionParams, $config);
As we can see to obtain a DBAL connection we use a factory method in DriverManager class. We can easily implements it in our service container:
# databases.yml
parameters:
doctrine.dbal.configuration: Doctrine\DBAL\Configuration
doctrine.dbal.drivermanager: Doctrine\DBAL\DriverManager
database.db1:
driver: pdo_sqlite
memory: true
database.db2:
driver: pdo_pgsql
dbname: testdb
user: username
password: password
host: 127.0.0.1
services:
dbal_configuartion:
class: %doctrine.dbal.configuration%
db1:
factory_class: %doctrine.dbal.drivermanager%
factory_method: getConnection
arguments: [%database.db1%]
db2:
factory_class: %doctrine.dbal.drivermanager%
factory_method: getConnection
arguments: [%database.db2%]
But if we run again our example Symfony will throws us one error:
RuntimeException: Please add the class to service “db1” even if it is constructed by a factory since we might need to add method calls based on compile-time checks.
If we use this service container configuration outside Symfony2 application it works (remember we can use Symfony’s Dependency Injection Container outside Symfony application as a component. Example here). But if we want to use it with Symfony2 we need to set the “class”, even here when we only need the static constructor, so we change it to:
# databases.yml
parameters:
doctrine.dbal.configuration: Doctrine\DBAL\Configuration
doctrine.dbal.drivermanager: Doctrine\DBAL\DriverManager
database.db1:
driver: pdo_sqlite
memory: true
database.db2:
driver: pdo_pgsql
dbname: testdb
user: username
password: password
host: 127.0.0.1
services:
dbal_configuartion:
class: %doctrine.dbal.configuration%
db1:
class: %doctrine.dbal.drivermanager%
factory_class: %doctrine.dbal.drivermanager%
factory_method: getConnection
arguments: [%database.db1%]
db2:
class: %doctrine.dbal.drivermanager%
factory_class: %doctrine.dbal.drivermanager%
factory_method: getConnection
arguments: [%database.db2%]
And that’s all. We can use DBAL instead of PDO in our database connections.
UPDATE:
After publishing this post someone comment me Doctrine allows us to do it “out of the box” within Symfony with its DoctrineBundle:
https://github.com/doctrine/DoctrineBundle/blob/master/Resources/doc/configuration.rst#doctrine-dbal-configuration