SAAS模式下的Symfony 1.4项目 - 多个数据库

时间:2014-03-05 09:12:53

标签: php doctrine symfony1 symfony-1.4 doctrine-1.2

我有一个Symfony 1.4项目,我想在SAAS模式下为多个客户使用。 我们的想法是拥有多个域和数据库,但始终使用相同的代码。我也不想为每个新客户改变项目中的任何内容:一切都必须是动态的。

我现在已经尝试了几个小时来覆盖database.yml配置,但它并没有真正成功。我在ProjectConfiguration.class.php的开头添加了:

require_once '/path/to/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine.php';
spl_autoload_register(array('Doctrine', 'autoload'));
$manager = Doctrine_Manager::getInstance();

$serverName = $_SERVER['SERVER_NAME'];
if(preg_match("#\.saas-domain\.com$#", $serverName))
  $dbname = "db-" . preg_replace("#\.saas-domain\.com$#", "", $serverName);
else
  $dbname = "db-default";

$dsn      = "mysql:dbname=$dbname;host=localhost";
$user     = 'dbuser';
$password = 'dbpsw';

try {
  $dbh  = new PDO($dsn, $user, $password);
  $conn = Doctrine_Manager::connection($dbh);
} catch (PDOException $e) {
  die("Can't find that database");
}

我试图将此代码放在setup()方法的末尾,同样的事情:似乎没有使用它。

正如您所看到的,我想推断出要在域中使用的数据库(Apache中的ServerName)。

我的最后一个选择是手动更改缓存中生成的每个config_database.yml.php文件(实际上只更改一个并使用符号链接),但我真的不想这样做。

所以我的问题是:

  • 是否可以覆盖database.yml配置?
  • 如果没有,有没有办法可以删除此文件或忽略它并设置手动学说配置?
  • 我还没有考虑过任何其他解决方案吗?

修改

我设法提出了一个解决方案(在this article的帮助下)。这可能不是最好的方法,但至少结果还可以。 我们的想法是使用Symfony的过滤器来替换数据库YAML文件创建的连接:

config/filters.yml中添加以下内容:

myDBConnectionFilter:
  class: myDBConnectionFilter

然后创建此myDBConnectionFilter类并将其放在Symfony的自动加载器(大多数情况下为lib)可以找到的任何位置。以下是您可以在此课程中使用的代码示例:

<?php

class myDBConnectionFilter extends sfFilter
{
    public function execute($filterChain){
        if ($this->isFirstCall())
        {
            $serverName = $_SERVER['SERVER_NAME'];
            if(preg_match("#\.saas-domain\.com$#", $serverName))
              $dbname = "db-" . preg_replace("#\.saas-domain\.com$#", "", $serverName);
            else
              $dbname = "db-default";

            $dsn      = "mysql:dbname=$dbname;host=localhost";
            $user     = 'user';
            $password = 'password';

            $manager = Doctrine_Manager::getInstance();

            try {
              $default = $manager->getConnection('dbconnection');
              Doctrine_Manager::getInstance()->closeConnection($default);

              $dbh  = new PDO($dsn, $user, $password);
              $conn = Doctrine_Manager::connection($dbh, 'dbconnection');
            } catch (Exception $e) {
                die("Error : " . $e->getMessage());
            }
        }

        $filterChain->execute();
    }
}

然后你需要清除Symfony的缓存。

此代码从Doctrine_Manager检索连接,关闭它,然后创建一个具有相同名称的新连接以替换它。在这种情况下,连接称为dbconnection。连接的名称是database.yml中使用的名称。

正如我所说,这不是最好的方法,因为这个方法与数据库建立了两个连接,而不是一个。所以,如果有人有更好的解决方案,我会接受它!

0 个答案:

没有答案