How to use multiple versions at the same time in a

2019-06-25 22:59发布

问题:

Context first: Apigility driven application based on Zend Framework 2. In the first version (V1) I was using the ZfcBase DbMapper for the model layer. Now I'm implementing the V2 with Doctrine 2 as ORM.

Apigility provides an easy switching between versions and every version can use its own DB adapter:

/config/autoload/global.php / /config/autoload/local.php

<?php
return array(
    ...
    'db' => array(
        'adapters' => array(
            'DB\\myproject_v1' => array(
                // settings (driver, hostname, database, driver_options)
                // credentials (username, password)
                ...
            ),
            'DB\\myproject_v2' => array(
                // settings (driver, hostname, database, driver_options)
                // credentials (username, password)
                ...
            ),
        ),
    ),
    ...
);

So, to use another version as default with another database behind it only the URL needs to be changed:

myproject.tld/my-endpoint    <-- version set to default
myproject.tld/v1/my-endpoint <-- version 1
myproject.tld/v2/my-endpoint <-- version 2

I want to add Doctrine 2 to my application, so I extended my local.php like here shown:

<?php
return array(
    ...
    'doctrine' => array(
        'connection' => array(
            'orm_default' => array(
                'driverClass' => 'Doctrine\DBAL\Driver\PDOMySql\Driver',
                'params' => array(
                    // settings (host, port, dbname)
                    // credentials (user, password)
                    ...
                ),
            ),
        ),
    ),
    ...
);

It's working, but now I don't have the flexibility for switching between the versions / for using different versions with different databases behind them. My adapter settings are getting overridden by the doctrine connection configs or just ignored.

How to combine Doctrine with the versioning flexibility of Apigility? How to configure the DB connection in an Apigility application with Doctrine and stay able to switch between the verions / to use multiple versions at the same time?

回答1:

The following section of your config:

[
    'db'=>[
        'adapters' => [
            'DB\\myproject_v1' => [],
            'DB\\myproject_v2' => [],
        ]
    ]
]

configures an abstract factory that registers the service names DB\\myproject_v1 and DB\\myproject_v2 with db adapter instances.

It is the part of the configuration below that actually assigns the adapter to your DB connected resource:

'db-connected' => array(
    'YourDBConnectedResource' => array(
        'adapter_name'     => 'DB\\myproject_v1',
    ),
),

Doctrine provides its own abstract factory and configuration, so to make Apigility work with Doctrine as your database adapter, you just have to tweak the configuration a bit. First, lets add a second connection to your doctrine config to help illustrate the change.

return [
    'doctrine' => [
        'connection' => [
            'orm_default' => [ // you don't have to use orm_default, you can arbitrarily name this version1
                'driverClass' => 'Doctrine\DBAL\Driver\PDOMySql\Driver',
                'params' => [
                    // settings (host, port, dbname)
                    // credentials (user, password)

                ],
            ],
            'version2' => [
                'driverClass' => 'Doctrine\DBAL\Driver\PDOMySql\Driver',
                'params' => [
                    // settings (host, port, dbname)
                    // credentials (user, password)
                ],
            ],            
        ],
    ],
];

Now, your DB adapter names are doctrine.connection.orm_default and doctrine.connection.version2. So you substitute those in your db-connected configuration block.

'db-connected' => [
    'My\\Endpoint\\V1\\Rest\\MyResource' => [
        'adapter_name'     => 'doctrine.connection.orm_default',
    ],
    'My\\Endpoint\\V2\\Rest\\MyResource' => [
        'adapter_name'     => 'doctrine.connection.version2',
    ],
],