подключение к двум различным базам данных с Zend Framework - PullRequest
11 голосов
/ 04 октября 2009

У меня есть интранет-сайт среднего размера, полностью написанный на Zend FW. База данных для интрасети расположена на другом сервере. Теперь мне нужно расширить интранет новыми функциональными возможностями. Для этого мне нужно подключиться к другой базе данных на том же сервере (и той же СУБД).

Вопрос сейчас: каков наилучший способ сделать это? Должен ли я создать новый объект Zend_Config и новый Zend_Db_Adapter? Или я должен использовать существующий и попытаться использовать "use otherdbname;" оператор для подключения в том же сеансе к новой базе данных?

Или есть еще лучший способ сделать это?

Ответы [ 5 ]

11 голосов
/ 04 октября 2009

Один вариант - зарегистрировать 2 дескриптора базы данных из вашего bootstrap.php, по одному для каждого соединения. E.g.:

$parameters = array(
                    'host'     => 'xx.xxx.xxx.xxx',
                    'username' => 'test',
                    'password' => 'test',
                    'dbname'   => 'test'
                   );
try {
    $db = Zend_Db::factory('Pdo_Mysql', $parameters);
    $db->getConnection();
} catch (Zend_Db_Adapter_Exception $e) {
    echo $e->getMessage();
    die('Could not connect to database.');
} catch (Zend_Exception $e) {
    echo $e->getMessage();
    die('Could not connect to database.');
}
Zend_Registry::set('db', $db);

$parameters = array(
                    'host'     => 'xx.xxx.xxx.xxx',
                    'username' => 'test',
                    'password' => 'test',
                    'dbname'   => 'test'
                   );
try {
    $db = Zend_Db::factory('Pdo_Mysql', $parameters);
    $db->getConnection();
} catch (Zend_Db_Adapter_Exception $e) {
    echo $e->getMessage();
    die('Could not connect to database.');
} catch (Zend_Exception $e) {
    echo $e->getMessage();
    die('Could not connect to database.');
}
Zend_Registry::set('db2', $db);

В ваших контроллерах (например):

public function init()
{
     $this->db = Zend_Registry::get('db');
     $this->db2 = Zend_Registry::get('db2');
}

public function fooAction()
{
    $data = $this->db2->fetchAll('select foo from blah');
    ...
}
3 голосов
/ 04 октября 2009

Я использую этот Config.ini, вы также можете использовать его:

[production]
#Debug output
phpSettings.display_startup_errors = 0
phpSettings.display_errors = 0
# Include path
includePaths.library = APPLICATION_PATH "/../library"
# Bootstrap
bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
bootstrap.class = "Bootstrap"
# Front Controller
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
resources.frontController.env = APPLICATION_ENV
# Layout
#resources.layout.layout = "layout"
#resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"
# Views
resources.view.encoding = "UTF-8"
resources.view.basePath = APPLICATION_PATH "/views/"
# Database
resources.db.adapter = "pdo_mysql"
resources.db.params.host = "localhost"
resources.db.params.username = "root"
resources.db.params.password = ""
resources.db.params.dbname = "world"
resources.db.isDefaultTableAdapter = true
# Session
resources.session.save_path = APPLICATION_PATH "/../data/session"
resources.session.remember_me_seconds = 864000
[testing : production]
#Debug output
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
# Database
resources.db.params.dbname = "myproject_testing"
[development : production]
#Debug output
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
# Database
resources.db.params.dbname = "myproject_development"

вы можете использовать его для производства, тестирования и разработки, если вам необходимо одновременно подключиться к другой БД, вы можете удвоить конфигурацию базы данных, например:

resources.db2.adapter = "pdo_mysql"
resources.db2.params.host = "localhost"
resources.db2.params.username = "root"
resources.db2.params.password = ""
resources.db2.params.dbname = "world"
resources.db2.isDefaultTableAdapter = true

тогда вы можете загрузить его на бутстап или куда угодно :) и это также просто

3 голосов
/ 04 октября 2009

Я думаю, это зависит от того, как часто вам приходится переключать базы данных. Использование двух разных адаптеров позволит более четко различать две базы данных и будет моим предпочтением.

Когда вы переключаете базы данных на одном адаптере, вам наверняка будет сложно отследить, какая база данных в данный момент активна - имейте в виду, что ваше соединение с базой данных, скорее всего, является одиночным, который передается между модулями, их контроллерами и их соответствующими моделями.

Третий вариант - использовать явные имена таблиц во всем приложении. Например, MySQL предоставляет синтаксис db_name.table_name для адресации таблиц в разных базах данных на одном сервере. База данных по умолчанию не имеет значения, поэтому Zend_Db_Table и Zend_Db_Select поддерживают этот синтаксис "из коробки".

EDIT:

Я должен добавить, что опции 2 и 3 будут работать, только если у пользователя вашей базы данных есть соответствующие права доступа ко всем базам данных, таблицам и столбцам, которые вы хотите использовать. Вариант 1 будет единственным оставленным вариантом, если для вашей базы данных требуется отдельный пользователь в каждой из ваших баз данных.

2 голосов
/ 05 августа 2014

Из того, что я нашел здесь , чтобы использовать разные базы данных в приложении Zend, вы можете выбрать один из этих двух возможных способов в зависимости от ваших потребностей:

- Наличие одного хоста / пользователя для двух баз данных

Вы можете указать базу данных, которую хотите использовать для инициализации переменной $_schema в модели, следующим образом:

class Customer extends Zend_Db_Table_Abstract
{
    protected $_name   = 'customer';
    protected $_schema = 'db_name';

    ....
}

- Наличие разных хостов / пользователей для двух баз данных

В application.ini вы должны записать конфигурацию для обеих баз данных следующим образом:

resources.multidb.local.adapter                 = pdo_mysql
resources.multidb.local.host                    = localhost
resources.multidb.local.username                = user
resources.multidb.local.password                = ******
resources.multidb.local.dbname                  = db_name_1
resources.multidb.local.default                 = true

resources.multidb.remote.adapter                = pdo_mysql
resources.multidb.remote.host                   = remote_host
resources.multidb.remote.username               = user
resources.multidb.remote.password               = ******
resources.multidb.remote.dbname                 = db_name_2
resources.multidb.remote.default                = false

Добавление блока _initDbRegistry в начальную загрузку добавит базы данных в реестр, поэтому вы сможете получить к ним доступ:

<?php

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{

    /**
     * Add databases to the registry
     * 
     * @return void
     */
    public function _initDbRegistry()
    {
        $this->bootstrap('multidb');
        $multidb = $this->getPluginResource('multidb');
        Zend_Registry::set('db_local', $multidb->getDb('local')); //db_local is going to be the name of the local adapter
        Zend_Registry::set('db_remote', $multidb->getDb('remote')); //db_remote is going to be the name of the remote adapter
    }

}

Теперь вы можете указать адаптер, который вы хотите использовать для каждой модели, следующим образом:

class Customer extends Zend_Db_Table_Abstract
{
    protected $_name    = 'customer';
    protected $_schema  = 'db_name_1';
    protected $_adapter = 'db_local'; //Using the local adapter

    ....
}

class Product extends Zend_Db_Table_Abstract
{
    protected $_name    = 'product';
    protected $_schema  = 'db_name_2';
    protected $_adapter = 'db_remote'; //Using the remote adapter

    ....
}
2 голосов
/ 01 июня 2013

одним из лучших способов является:

создать новую таблицу моделей для любой таблицы в базе данных:

class Article extends Zend_Db_Table_Abstract  
{    
    protected $_name = 'id';
    public  function __construct()  {
        $adaptor = new Zend_Db_Adapter_Pdo_Mysql(array(
            'host'     => 'localhost',
            'username' => 'username',
            'password' => 'password',
            'dbname'   => 'database'

        ));
        $this->_db = $adaptor;
        parent::__construct();
    }

    // your functions goes here
    public function add($data) {
        // any syntax
    }
}
...