如何在Zend Framework 2中配置(和使用)多个数据库?目前我在global.php中有这个:
return array(
'db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=my_db;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
'username' => 'user',
'password' => '******',
),
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter' => 'Zend\Db\Adapter\AdapterServiceFactory',
),
),
);
但是我没有办法增加第二个。
答案 0 :(得分:51)
如果查看Zend \ Db \ Adapter \ AdapterServiceFactory,您将看到适配器配置仅指向一个键'db'
。这意味着它构建的适配器将始终使用此(唯一)配置密钥。
我建议您创建一个如下所示的工厂:
namespace Your\Namespace;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\Db\Adapter\Adapter;
class MyAdapterFactory implements FactoryInterface
{
protected $configKey;
public function __construct($key)
{
$this->configKey = $key;
}
public function createService(ServiceLocatorInterface $serviceLocator)
{
$config = $serviceLocator->get('Config');
return new Adapter($config[$this->configKey]);
}
}
在主模块(或任何其他模块)中,将以下内容添加到Module.php文件中,以将适配器工厂声明为Zend Service Manager:
use Your\Namespace\MyAdapterFactory;
use Zend\ModuleManager\Feature\ServiceProviderInterface;
class Module implements ServiceProviderInterface{
//Previous code
public function getServiceConfig()
{
return array(
'factories' => array(
'myadapter1' => new MyAdapterFactory('dbconfigkey1'),
'myadapter2' => new MyAdapterFactory('dbconfigkey2'),
),
);
}
//...
全局配置现在应该如下所示:
return array(
'dbconfigkey1' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=my_db;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
'username' => 'user',
'password' => '******',
),
'dbconfigkey2' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=my_db2;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
'username' => 'user',
'password' => '******',
),
);
使用您需要使用服务管理器调用它们的适配器:
$adapter1=$serviceManager->get('myadapter1');
$adapter2=$serviceManager->get('myadapter2');
抽象服务工厂现在是zf2 Zend \ Db模块的一部分。可以在“适配器”子键下添加多个配置键:
'db'=> array(
'adapters'=>array(
'adapter' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=test;host=localhost',
'username' => 'readCredential',
'password' => '****'
),
'adapter2' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=test;host=localhost',
'username' => 'rwCredential',
'password' => '****'
),
)
),
但是,AbstractServiceFactory需要“手动”添加,因为默认情况下不是这样:
'service_manager' => array(
'abstract_factories' => array(
'Zend\Db\Adapter\AdapterAbstractServiceFactory',
)
),
可以像以前一样访问适配器:
$adapter1=$serviceManager->get('adapter');
$adapter2=$serviceManager->get('adapter2');
从性能角度来看,第二种方法更好:一个对象将被实例化(抽象工厂)以(可能)创建不同的适配器。而在之前的方法中,每个配置创建了一个对象。
答案 1 :(得分:3)
Zend Framework 2.2附带了abstract_factories Zend\Db\Adapter\AdapterAbstractServiceFactory
,它允许我们配置多个命名的数据库适配器实例。这是一步一步做到的:
在'service_manager'键下的'abstract_factories'类型中注册Zend\Db\Adapter\AdapterAbstractServiceFactory
。
//配置/自动加载/ global.php // .... config / autoload / global.php的一部分 'service_manager'=>阵列( 'abstract_factories'=>阵列( '的Zend \ DB \适配器\ AdapterAbstractServiceFactory', ) ),
在config/autoload/global.php
//配置/自动加载/ global.php // .... config / autoload / global.php的一部分
'db' => array(
'adapters' => array(
'db1' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=zf2_staging;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
'db2' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=zf2_test;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
),
),
config/autoload/local.php
//配置/自动加载/ local.php
return array(
'db' => array(
'adapters' => array(
'db1' => array(
'username' => 'root',
'password' => '',
),
'db2' => array(
'username' => 'other_user',
'password' => 'other_user_passwd',
),
),
),
);
使用'db1'或'db2'作为ServiceManager的数据库适配器调用适配器
$ SM->获得( 'DB1');
$ SM->获得( 'DB2');
如果您需要将$sm->get(‘Zend\Db\Adapter\Adapter’)
作为主适配器,'db1'和'db2'作为特定用途的其他适配器,那么您需要直接在db下定义主适配器,因此{{1}的配置将如下所示:
//配置/自动加载/ global.php
config/autoload/global.php
return array(
'db' => array(
//this is for primary adapter....
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=zf21_learn;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
//other adapter when it needed...
'adapters' => array(
'db1' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=zf2_staging;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
'db2' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=zf2_test;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
),
),
'service_manager' => array(
// for primary db adapter that called
// by $sm->get('Zend\Db\Adapter\Adapter')
'factories' => array(
'Zend\Db\Adapter\Adapter'
=> 'Zend\Db\Adapter\AdapterServiceFactory',
),
// to allow other adapter to be called by
// $sm->get('db1') or $sm->get('db2') based on the adapters config.
'abstract_factories' => array(
'Zend\Db\Adapter\AdapterAbstractServiceFactory',
),
),
);
的配置也应如下所示:
//配置/自动加载/ local.php
config/autoload/global.local.php