在zf2中配置多个数据库

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)

截至2.2版

抽象服务工厂现在是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)

从性能角度来看,第二种方法更好:一个对象将被实例化(抽象工厂)以(可能)创建不同的适配器.而在之前的方法中,每个配置创建一个对象.


Rit*_*esh 5

我在https://samsonasik.wordpress.com/2013/07/27/zend-framework-2-multiple-named-db-adapter-instances-using-adapters-subkey/上找到了更好的解释

\n\n

Zend Framework 2.2 附带了abstract_factories Zend\\Db\\Adapter\\AdapterAbstractServiceFactory,它允许我们配置多个命名的数据库适配器实例。这是一步一步来做到的:

\n\n
    \n
  1. 在 \xe2\x80\x98abstract_factories\xe2\x80\x99 类型下注册Zend\\Db\\Adapter\\AdapterAbstractServiceFactory\xe2\x80\x98service_manager\xe2\x80\x99 密钥。

    \n\n

    //config/autoload/global.php\n//.... config/autoload/global.php 的一部分\n \'service_manager\' => array( \n \'abstract_factories\' => array(\n \'Zend\\Db\\Adapter\\AdapterAbstractServiceFactory\',\n ),\n ),

  2. \n
  3. 配置 \xe2\x80\x98db\xe2\x80\x99 项下的 \xe2\x80\x98adapters\xe2\x80\x99 子项config/autoload/global.php

  4. \n
\n\n

//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\n
    \n
  1. 配置 \xe2\x80\x98db\xe2\x80\x99 项下的 \xe2\x80\x98adapters\xe2\x80\x99 子项config/autoload/local.php
  2. \n
\n\n

//配置/自动加载/local.php

\n\n
return 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
    \n
  1. 使用 \xe2\x80\x98db1\xe2\x80\x99 或 \xe2\x80\x98db2\xe2\x80\x99 作为来自 ServiceManager 的数据库适配器来调用适配器

    \n\n

    $sm->get(\'db1\');

    \n\n

    $sm->get(\'db2\');

  2. \n
\n\n

如果您需要将$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如下:

\n\n

//配置/自动加载/global.php

\n\n
return 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应该配置如下:

\n\n

//配置/自动加载/local.php

\n\n
return 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