Robert Basic's blog

Using Doctrine DBAL with Zend Expressive

by Robert Basic on December 22, 2016.

The Doctrine project comes with a database abstraction and access layer — Doctrine DBAL — which I prefer over other abstraction layers like Zend DB.

My good friend James, aka Asgrim, has written already how to integrate Zend Expressive and Doctrine ORM.

But what if want to use only the DBAL with Zend Expressive, and not the entire ORM?

It’s pretty easy as all we need to do is write one short factory that will create the database connection using the connection parameters we provide to it:

src/App/Infrastructure/Database/ConnectionFactory.php

<?php declare(strict_types=1);

namespace App\Infrastructure\Database;

use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Driver\Connection;
use Interop\Container\ContainerInterface;

class ConnectionFactory
{
    public function __invoke(ContainerInterface $container) : Connection
    {
        $config = $container->get('config');
        $connectionParams = $config['db'];

        return DriverManager::getConnection($connectionParams);
    }
}

Configuration of the database connection is pretty straightforward as well:

config/database.php

<?php declare(strict_types=1);

return [
    'db' => [
        'driver' => 'pdo_pgsql',
        'dbname' => 'database_name',
        'user' => 'username',
        'password' => 'password',
        'host' => 'localhost',
        'port' => 5432,
    ]
];

For other options and possible values, take a look at the configuration documentation.

Next, we configure a container-interop service locator, like Zend ServiceManager to be able to access the database connection in parts of the application where we need it. This configuration consists of mapping a factory name to the ConnectionFactory factory:

config/dependencies.php

<?php declare(strict_types=1);

return [
    'dependencies' => [
        'factories' => [
            'db' => App\Infrastructure\Database\ConnectionFactory::class,
            // other factories ...
        ],
        // other type of dependencies ...
    ]
];

Now all we need to access the database connection is to grab it from the ContainerInterface container somewhere in our application and we’re all set:

src/App/SomeObjectFactory.php

<?php declare(strict_types=1);

namespace App;

use Interop\Container\ContainerInterface;

class SomeObjectFactory
{
    public function __invoke(ContainerInterface $container) : SomeObject
    {
        $connection = $container->get('db');
        return new SomeObject($connection);
    }
}

We can now use this $connection object to further create the query builder, work with transactions, the schema manager and other features the Doctrine DBAL provides us. Nice and easy.

Happy hackin’!

Tags: dbal, doctrine, zend expressive.
Categories: Development, Programming, Software.