Как динамически (в зависимости от 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, используя нужную мне БД.

Другие вопросы по тегам