Reputation: 380
in ZF2 it was possible to configurate multiple adapters like this in the module.config.php
:
'db' => array(
'adapters'=>array(
'db1' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=zf2;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
'username' => 'zf2',
'password' => 'zf2test',
),
'db2' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=zf1;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
'username' => 'zf1',
'password' => 'zf1test',
),
)
),
In the controller factory I could get them via the ServiceManager:
class AlbumControllerFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$albumTable = $serviceLocator->getServiceLocator()->get('Album\Model\AlbumTable');
$db1Adapter = $serviceLocator->getServiceLocator()->get('db1');
$db2Adapter = $serviceLocator->getServiceLocator()->get('db2');
return new AlbumController($albumTable, $db1Adapter, $db2Adapter);
}
}
Now I'm trying to do the same in Zend Framework 3 - but this nested array configuration doesn't work:
Fatal error: Uncaught exception 'Zend\Db\Adapter\Exception\InvalidArgumentException' with message 'createDriver expects a "driver" key to be present inside the parameters' in /var/www/USER/teckert/zf3/vendor/zendframework/zend-db/src/Adapter/Adapter.php:262
I think that in ZF 2 the adapters
key are already handled when the dbAdapter is trying to create the driver - but this is not happening in ZF 3.
Any hints are warmly welcomed...
The manual of the zend-db with the adapters section wasn't clear enough for me
EDIT
According to this doc I've added the following snippet to the global config file:
'service_manager' => [
'abstract_factories' => [
\Zend\Db\Adapter\AdapterAbstractServiceFactory::class,
],
],
While trying to get the dbAdapter with $container->get('db1')
in my AlbumTableFactory
I get this error:
Unable to resolve service "db1 to a factory; are you certain you provided it during configuration?
Upvotes: 2
Views: 5386
Reputation: 380
Okay I finally resolved the problem.
As mentioned by @Pieter I needed the following array content in my config.php
:
'service_manager' => [
'abstract_factories' => [
\Zend\Db\Adapter\AdapterAbstractServiceFactory::class,
],
],
Additionally I had to change the process my classes and dependent factories are talking to each other.
AlbumControllerFactory
is called and get's the dependent AlbumTable
service ($container->get(AlbumTable::class);
) which then triggers the AlbumTableFactory
AlbumTableFactory
then is preparing the constructor injection for the AlbumTable
with $tableGateway = $container->get(AlbumTableGateway::class);
AlbumTableFactory
and the AlbumTableGatewayFactory
into one AbstractFactoryInterface
(I removed the AlbumTableGatewayFactory completely)// AlbumTableFactory implements AbstractFactoryInterface
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$dbAdapter = $container->get('db1');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Album());
$tableGateway = new TableGateway('album', $dbAdapter, null, $resultSetPrototype);
return new AlbumTable($tableGateway);
}
Upvotes: 1
Reputation: 1774
Make sure you've added Zend\Db\Adapter\AdapterAbstractServiceFactory
to the abstract_factories
array of the ServiceManager configuration.
This abstract factory is responsible for instantiating the individual database adapters. Also, check whether your Album\Model\AlbumTable
factory retrieves the database adapter with the correct name.
Upvotes: 2