tih*_*ihe 28 php zend-framework2
如何在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',
),
),
);
Run Code Online (Sandbox Code Playgroud)
但我没有看到添加第二个的方法.
yec*_*bbi 52
如果查看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]);
}
}
Run Code Online (Sandbox Code Playgroud)
在主模块(或任何其他模块)中,将以下内容添加到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'),
),
);
}
//...
Run Code Online (Sandbox Code Playgroud)
全局配置现在应该如下所示:
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' => '******',
),
);
Run Code Online (Sandbox Code Playgroud)
使用您需要使用服务管理器调用它们的适配器:
$adapter1=$serviceManager->get('myadapter1');
$adapter2=$serviceManager->get('myadapter2');
Run Code Online (Sandbox Code Playgroud)
抽象服务工厂现在是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' => '****'
),
)
),
Run Code Online (Sandbox Code Playgroud)
但是,AbstractServiceFactory需要"手动"添加,因为默认情况下不是这样:
'service_manager' => array(
'abstract_factories' => array(
'Zend\Db\Adapter\AdapterAbstractServiceFactory',
)
),
Run Code Online (Sandbox Code Playgroud)
适配器可以像以前一样访问:
$adapter1=$serviceManager->get('adapter');
$adapter2=$serviceManager->get('adapter2');
Run Code Online (Sandbox Code Playgroud)
从性能角度来看,第二种方法更好:一个对象将被实例化(抽象工厂)以(可能)创建不同的适配器.而在之前的方法中,每个配置创建一个对象.
我在https://samsonasik.wordpress.com/2013/07/27/zend-framework-2-multiple-named-db-adapter-instances-using-adapters-subkey/上找到了更好的解释
\n\nZend Framework 2.2 附带了abstract_factories Zend\\Db\\Adapter\\AdapterAbstractServiceFactory
,它允许我们配置多个命名的数据库适配器实例。这是一步一步来做到的:
在 \xe2\x80\x98abstract_factories\xe2\x80\x99 类型下注册Zend\\Db\\Adapter\\AdapterAbstractServiceFactory
\xe2\x80\x98service_manager\xe2\x80\x99 密钥。
//config/autoload/global.php\n//.... config/autoload/global.php 的一部分\n \'service_manager\' => array( \n \'abstract_factories\' => array(\n \'Zend\\Db\\Adapter\\AdapterAbstractServiceFactory\',\n ),\n ),
配置 \xe2\x80\x98db\xe2\x80\x99 项下的 \xe2\x80\x98adapters\xe2\x80\x99 子项config/autoload/global.php
//config/autoload/global.php\n//.... config/autoload/global.php 的一部分
\n\n\'db\' => array(\n \'adapters\' => array(\n\n \'db1\' => array(\n \'driver\' => \'Pdo\',\n \'dsn\' => \'mysql:dbname=zf2_staging;host=localhost\',\n \'driver_options\' => array(\n PDO::MYSQL_ATTR_INIT_COMMAND => \'SET NAMES \\\'UTF8\\\'\'\n ),\n ),\n\n \'db2\' => array(\n \'driver\' => \'Pdo\',\n \'dsn\' => \'mysql:dbname=zf2_test;host=localhost\',\n \'driver_options\' => array(\n PDO::MYSQL_ATTR_INIT_COMMAND => \'SET NAMES \\\'UTF8\\\'\'\n ),\n ),\n ),\n),\n
Run Code Online (Sandbox Code Playgroud)\n\nconfig/autoload/local.php
//配置/自动加载/local.php
\n\nreturn array(\n \'db\' => array(\n \'adapters\' => array(\n \'db1\' => array(\n \'username\' => \'root\',\n \'password\' => \'\',\n ),\n \'db2\' => array(\n \'username\' => \'other_user\',\n \'password\' => \'other_user_passwd\',\n ),\n ),\n ),\n);\n
Run Code Online (Sandbox Code Playgroud)\n\n使用 \xe2\x80\x98db1\xe2\x80\x99 或 \xe2\x80\x98db2\xe2\x80\x99 作为来自 ServiceManager 的数据库适配器来调用适配器
\n\n$sm->get(\'db1\');
\n\n$sm->get(\'db2\');
如果您需要将$sm->get(\xe2\x80\x98Zend\\Db\\Adapter\\Adapter\xe2\x80\x99)
\xe2\x80\x98db1\xe2\x80\x99 和 \xe2\x80\x98db2\xe2\x80\x99 作为主适配器作为特定用途的其他适配器,那么您需要直接在下面定义主适配器db,所以配置config/autoload/global.php
如下:
//配置/自动加载/global.php
\n\nreturn array(\n \'db\' => array(\n //this is for primary adapter....\n \'driver\' => \'Pdo\',\n \'dsn\' => \'mysql:dbname=zf21_learn;host=localhost\',\n \'driver_options\' => array(\n PDO::MYSQL_ATTR_INIT_COMMAND => \'SET NAMES \\\'UTF8\\\'\'\n ),\n\n //other adapter when it needed...\n \'adapters\' => array(\n\n \'db1\' => array(\n \'driver\' => \'Pdo\',\n \'dsn\' => \'mysql:dbname=zf2_staging;host=localhost\',\n \'driver_options\' => array(\n PDO::MYSQL_ATTR_INIT_COMMAND => \'SET NAMES \\\'UTF8\\\'\'\n ),\n ),\n \'db2\' => array(\n \'driver\' => \'Pdo\',\n \'dsn\' => \'mysql:dbname=zf2_test;host=localhost\',\n \'driver_options\' => array(\n PDO::MYSQL_ATTR_INIT_COMMAND => \'SET NAMES \\\'UTF8\\\'\'\n ),\n ),\n\n ),\n ),\n \'service_manager\' => array(\n // for primary db adapter that called\n // by $sm->get(\'Zend\\Db\\Adapter\\Adapter\')\n \'factories\' => array(\n \'Zend\\Db\\Adapter\\Adapter\'\n => \'Zend\\Db\\Adapter\\AdapterServiceFactory\',\n ),\n // to allow other adapter to be called by\n // $sm->get(\'db1\') or $sm->get(\'db2\') based on the adapters config.\n \'abstract_factories\' => array(\n \'Zend\\Db\\Adapter\\AdapterAbstractServiceFactory\',\n ),\n ),\n);\n
Run Code Online (Sandbox Code Playgroud)\n\n这config/autoload/global.local.php
应该配置如下:
//配置/自动加载/local.php
\n\nreturn array(\n \'db\' => array(\n // for primary db adapter that called\n // by $sm->get(\'Zend\\Db\\Adapter\\Adapter\')\n \'username\' => \'root\',\n \'password\' => \'\',\n\n // to allow other adapter to be called by\n // $sm->get(\'db1\') or $sm->get(\'db2\') based on the adapters config.\n \'adapters\' => array(\n \'db1\' => array(\n \'username\' => \'root\',\n \'password\' => \'\',\n ),\n \'db2\' => array(\n \'username\' => \'other_user\',\n \'password\' => \'other_user_passwd\',\n ),\n ),\n ),\n);\n
Run Code Online (Sandbox Code Playgroud)\n