如何动态地(基于服务器环境)选择我的Kohana ORM连接到哪个数据库


How Do I Dynamically (based on server env) Choose Which Database My Kohana ORM Connects To?

这是针对Kohana v3.2的

如何动态选择 ORM 模型连接到的数据库?具体来说,我正在尝试更改ORM模型以在本地开发,暂存和生产环境中使用数据库。

Kohana指南告诉我,我可以通过在ORM模型上设置受保护的属性来设置数据库连接,如下所示:

class Model_Customer extends ORM
{
    protected $_db_group = 'local_db';
    protected $_table_name = 'customer';

这在本地开发时效果很好,但是当我进入舞台然后进行生产时呢?我宁愿不必在每次更改环境时都更改_db_group。我可以检查服务器变量以确定环境,但是由于我无法在类定义中执行任何逻辑,因此我一直无法找到动态设置db_group属性以匹配环境的方法。

可能有更好的方法来解决这个问题,我希望有人能够建议。谢谢。

在我看来,请检查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,
    ),
); 

正如我在对mobal答案的评论中所说,在使用相同的逻辑时,我会采取稍微不同的方法。

您可以在文档中看到,可以有多个数据库配置。在这种情况下,它可能看起来像这样

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);
    }
}

现在,每当您尝试获取默认实例(如果未设置_db_group,则在ORM中就是这种情况(并且在开发环境中时,开发配置将用于连接到数据库。

谢谢大家的想法。

我的用例涉及使用引用 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();
}

这会在调用 parent::construct() 之前设置 $_db_group 属性,该属性使用 I 所需的数据库初始化 ORM 的数据库连接。