Подтвердить что ты не робот

Настроить несколько баз данных в zf2

Как настроить (и использовать) несколько баз данных в 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',
        ),
    ),
);

Но я не вижу способа добавить второй.

4b9b3361

Ответ 1

Если вы посмотрите на Zend\Db\Adapter\AdapterServiceFactory, вы увидите, что ваша конфигурация адаптера указывает только на один ключ 'db'. Это означает, что адаптер, который он создает, всегда будет использовать этот (уникальный) ключ конфигурации.

Я рекомендую вам создать свой собственный factory, который будет выглядеть так:

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' => '******',
),

);

использовать адаптеры, необходимые для вызова их с помощью Service Manager:

$adapter1=$serviceManager->get('myadapter1');
$adapter2=$serviceManager->get('myadapter2');

Начиная с версии 2.2

Абстрактная служба factory теперь является частью модуля 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');

С точки зрения эффективности этот второй подход лучше: один объект будет создан (абстрактный factory), чтобы (потенциально) создать различные адаптеры. Если в предыдущем подходе был создан один объект для каждой конфигурации.

Ответ 2

Я нашел гораздо лучшее объяснение https://samsonasik.wordpress.com/2013/07/27/zend-framework-2-multiple-named-db-adapter-instances-using-adapters-subkey/

Zend Framework 2.2 поставляется с abstract_factories Zend\Db\Adapter\AdapterAbstractServiceFactory, который позволяет нам настраивать несколько экземпляров именованных DB-адаптеров. Это делается шаг за шагом:

  • Зарегистрируйте Zend\Db\Adapter\AdapterAbstractServiceFactory в 'abstract_factories type под ключом service_manager.

    //конфиг/автозагрузка/global.php //.... часть config/autoload/global.php   'service_manager' = > массив (       'abstract_factories' = > массив (           'Zend\Db\адаптер\AdapterAbstractServiceFactory',       ),   ),

  • Настроить "поддиапазоны" под ключом "db" в 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\''
            ),
        ),
    ),
),
  1. Настроить "адаптеры" под ключом "db" в 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',
            ),
        ),
    ),
);
  1. Адаптер вызовов с использованием 'db1 или' db2 в качестве адаптера db из ServiceManager

    $SM- > Get ( 'DB1');

    $SM- > Get ( 'db2');

Если вам нужно получить $sm->get(‘Zend\Db\Adapter\Adapter’) в качестве основного адаптера, 'db1 и' db2 в качестве другого адаптера для определенной цели, тогда вам нужно определить первичный адаптер непосредственно под db, поэтому конфигурация config/autoload/global.php будет выглядеть следующим образом:

//конфиг/автозагрузка/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',
        ),
    ),
);

config/autoload/global.local.php должен быть настроен так, как показано ниже:

//конфиг/автозагрузка/local.php

return array(
    'db' => array(
        // for primary db adapter that called
        // by $sm->get('Zend\Db\Adapter\Adapter')
        'username' => 'root',
        'password' => '',

        // to allow other adapter to be called by
        // $sm->get('db1') or $sm->get('db2') based on the adapters config.
        'adapters' => array(
            'db1' => array(
                'username' => 'root',
                'password' => '',
            ),
            'db2' => array(
                'username' => 'other_user',
                'password' => 'other_user_passwd',
            ),
        ),
    ),
);