Подключение к двум различным базам данных с Zend Framework
У меня есть сайт интрасети среднего размера, который полностью написан в Zend FW. База данных для интрасети находится на другом сервере. Теперь мне нужно расширить интрасеть с помощью некоторых новых функций. Для этого мне нужно подключиться к другой базе данных на том же сервере (и той же СУБД).
Вопрос сейчас: Каков наилучший способ сделать это? Должен ли я создать новый объект Zend_Config и новый Zend_Db_Adapter? Или я должен использовать существующий и попробовать с помощью "use otherdbname;" оператора для подключения в рамках одного сеанса к новой базе данных?
Или есть еще лучший способ сделать это?
Ответы
Ответ 1
Один из вариантов - зарегистрировать 2 дескриптора базы данных из bootstrap.php
, по одному для каждого соединения. Например:.
$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');
...
}
Ответ 2
Я думаю, это зависит от того, как часто вам приходится переключать базы данных. Использование двух разных адаптеров будет более четко различать две базы данных и будет моим предпочтением.
Когда вы переключаете базы данных на свой один адаптер, вам наверняка будет сложно отслеживать, какая база данных активна в настоящий момент - помните, что ваше соединение с базой данных, скорее всего, одноэлементное, которое передается между модулями, их контроллерами и их соответствующие модели.
Третий вариант - использовать явные имена таблиц в вашем приложении. Например, MySQL предоставляет db_name.table_name
-syntax для адресации таблиц в разных базах данных на одном сервере. База данных по умолчанию не имеет значения, и Zend_Db_Table
и Zend_Db_Select
поддерживают этот синтаксис из коробки.
EDIT:
Я должен добавить, что параметры 2 и 3 будут работать только в том случае, если пользователь базы данных имеет соответствующие права доступа для всех баз данных, таблиц и столбцов, которые вы хотите использовать. Вариант 1 будет единственным вариантом, если ваша база данных требует другого пользователя в каждой из ваших баз данных.
Ответ 3
Я использую этот 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
то вы можете загрузить его в bootstap или где вам нравится:)
и его также легко
Ответ 4
один из лучших способов:
создать новую таблицу моделей для любой таблицы в базе данных:
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
}
}
Ответ 5
Из того, что я нашел здесь, чтобы использовать разные базы данных в приложении 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
в bootstrap добавит базы данных в реестр, поэтому вы сможете получить к ним доступ:
<?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
....
}