Configure multi DB connections on ZF2

2019-02-17 15:16发布

I'm actualy a beginner in ZF2 I managed to use multiple BDD on the same application and it works. (I'm talking about this : configure multiple databases in zf2 ).

Though, I'd have a little question...

Is it ok to declare my custom factory in global.php ? (in the service_manager thing). Or do I need to declare it inside each module ? (in module.php)

Declaring it into global.php actualy works, but I was wondering if it's not breaking the spirit of the framework or something...

Thanks for your time !

Tounu

2条回答
神经病院院长
2楼-- · 2019-02-17 15:58

To connect multiple database at a time, follow these steps:

Step 1:

Create /module/MyModule/ and add into application.config.ini to access.

Step 2: Create Module.php in /module/MyModule/ directory with the following scripts

<?php

   namespace MyModule;
   use MyModule\MyAdapterFactory;
   use Zend\ModuleManager\Feature\ServiceProviderInterface;

   class Module implements ServiceProviderInterface{

public function getAutoloaderConfig()
{       
    return array(
        'Zend\Loader\StandardAutoloader' => array(
            'namespaces' => array(                              
                __NAMESPACE__  => __DIR__ . '/src/' . __NAMESPACE__.'/Db/Adapter/',
            ),
        ),
    );
}

public function getServiceConfig()
{   
    return array(
        'factories' => array(
            'adapter1'  => new MyAdapterFactory('db_adapter1'),
            'adapter2'  => new MyAdapterFactory('db_adapter2'),
        ),      
    );

}

 }

Step 3:

Create MyAdapterFactory.php in the path: /module/MyModule/src/MyModule/Db/Adapter/ with the following scripts.

   <?php 

     namespace MyModule;
     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]);
        }
      }

   ?>

Step 4:

Add the following scripts in your getServiceConfig().

             'YourModule\Model\YourTable' =>  function($sm) {
                $tableGateway = $sm->get('YourTableGateway');
                $table = new YourTable($tableGateway);
                return $table;
            },
            'YourTableGateway' => function ($sm) {  
                $adapter1 = $sm->get('adapter1');                 
                $resultSetPrototype = new ResultSet();
                $resultSetPrototype->setArrayObjectPrototype(new YourModel());
                return new TableGateway('tbl_name', $adapter1, null,                   $resultSetPrototype);
            }, 

Step 5:

Add method into your controller to access your table as below:

Declare this on start of the class:

protected $this->yourTable;

public function getYourTable()
{
    if (!$this->yourTable) {
        $sm = $this->getServiceLocator();
        $this->yourTable = $sm->get('YourModule\Model\YourTable');
    }       
    return $this->yourTable;
}

Then, You can call your Model methods for Select, Update, Insert using this function (getYourTable()) in your controller.

查看更多
再贱就再见
3楼-- · 2019-02-17 16:03

Store your connection settings in a local config:

config/autoload/local.php

this is in case you have multiple environments with different databases/connection credentials etc. for example, you may gave a staging setup, and a live setup, both using a separate database. You can also then use multiple connections inside your application this way too.

there's nothing to stop you setting up multiple connections in here, and using them as needed in your database adapters etc.

local.php

return array(
    /**
     * Database Connection One
     */
    'db' => array(
        'driver'    => 'pdo',
        'dsn'       => 'mysql:dbname=dbnamehere;host=localhost',
        'username'  => 'root',
        'password'  => '',
    ),
    /**
     * Database Connection Two
     */
    'db_two' => array(
        'driver'    => 'pdo',
        'dsn'       => 'mysql:dbname=anotherdb;host=localhost',
        'username'  => 'root',
        'password'  => '',
    ),

If you are using version control (you should be!) this also allows you to exclude the .local config files from your repository to avoid storing password etc in there, and allows for easier deployment to multiple environments.

You can setup multiple adapters to use different connections too:

global.php

return array(
    /**
     * Database Adapter(s)
     */
    'service_manager' => array(
        'factories' => array(
            /**
             * Adapter One - this factory will use the default 'db' connection
             */
            'Zend\Db\Adapter\Adapter'   => 'Zend\Db\Adapter\AdapterServiceFactory',
            /**
             * Adapter Two - use the second connection
             */
            'Application\Db\AdapterTwo' => function($sm) {
                 $config = $sm->get('Config');
                 return new Adapter($config['db_two']);
             },
        ),
    ),
);
查看更多
登录 后发表回答