Как динамически (в зависимости от env сервера) выбрать, к какой базе данных подключается мой Kohana ORM?
Это для Kohana v3.2
Как я могу динамически выбирать базу данных, к которой подключается модель ORM? В частности, я пытаюсь изменить модель ORM для работы с базами данных в моей локальной среде разработки, промежуточных и производственных средах.
Руководство Kohana говорит мне, что я могу установить соединение с базой данных, установив защищенное свойство для модели ORM следующим образом:
class Model_Customer extends ORM
{
protected $_db_group = 'local_db';
protected $_table_name = 'customer';
Это хорошо работает при локальной разработке, но что делать, когда я перехожу на сцену, а затем в производство? Я бы предпочел не менять группу _db_ каждый раз, когда я меняю среду. Я могу проверить серверные переменные, чтобы определить среду, но я не смог найти способ динамически установить свойство db_group для соответствия среде, так как я не могу сделать никакой логики в определении класса.
Возможно, есть лучший способ решения этой проблемы, который, я надеюсь, кто-то сможет предложить. Благодарю.
3 ответа
На мой взгляд, проверьте соединение в вашем database.php
Конфигурационный файл
return array
(
'default' => array
(
'type' => 'MySQL',
'connection' => array(
/**
* The following options are available for MySQL:
*
* string hostname server hostname, or socket
* string database database name
* string username database username
* string password database password
* boolean persistent use persistent connections?
* array variables system variables as "key => value" pairs
*
* Ports and sockets may be appended to the hostname.
*/
'hostname' => 'localhost',
'database' => (Kohana::$environment == Kohana::DEVELOPMENT) ? 'local_db' : 'kohana',
'username' => FALSE,
'password' => FALSE,
'persistent' => FALSE,
),
'table_prefix' => '',
'charset' => 'utf8',
'caching' => FALSE,
),
);
Как я сказал в комментарии к ответу мобала, я бы использовал немного другой подход, используя ту же логику.
Вы можете увидеть в документации, что возможно иметь несколько конфигов БД. В этом случае это может выглядеть так
return array(
'default' => array( /* regular connection */ ),
Kohana::DEVELOPMENT => array( /* connection for development */ )
);
Теперь вопрос: где должна быть логика, которая решает, какое соединение используется? Сначала я подумал ORM
класс был бы хорошим местом - но на самом деле я сомневаюсь в этом. Модель не должна заботиться о том, какое соединение используется.
Тем не мение, Database::instance()
выглядит правильно. Это метод, который определяет, какая конфигурация будет использоваться. И поэтому изменение его здесь повлияет на все, что использует базу данных - таким образом, идеальное место.
Поскольку Kohana использует классы-оболочки, вы можете создать файл APPPATH/classes/Database.php
и добавьте туда свои изменения вот так
class Database extends Kohana_Database {
public static function instance($name = NULL, $config = NULL) {
if ($name === NULL && Kohana::$environment == Kohana::DEVELOPMENT) {
$name = Kohana::DEVELOPMENT;
}
return parent::instance($name, $config);
}
}
Теперь всякий раз, когда вы пытаетесь получить экземпляр по умолчанию (который имеет место в ORM, если нет _db_group
) и находятся в среде разработки, для подключения к вашей базе данных будет использоваться конфигурация разработки.
Спасибо всем за идеи.
Мой вариант использования включает в себя работу с файлом конфигурации базы данных, который ссылается на 6 различных баз данных (2 базы данных по 3 среды для каждой из них).
Для моего конкретного случая это было самое простое решение, которое я мог найти, не беспокоясь о возможном загрязнении соединений с БД в других областях приложения.
Псевдокод:
public function __construct()
{
if ($_SERVER['HTTP_HOST'] == 'staging.acme.com')
{
$this->_db_group = 'db1_stage';
}
else if ($_SERVER['KOHANA_ENV'] == 'development')
{
$this->_db_group = 'db1_local';
}
else
{
$this->_db_group = 'db1_production';
}
parent::__construct();
}
Это устанавливает $_db_group
собственность перед звонком parent::construct()
который инициализирует соединение с базой данных для ORM, используя нужную мне БД.