我有一个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
文件(实际上只更改一个并使用符号链接),但我真的不想这样做。
所以我的问题是:
修改
我设法提出了一个解决方案(在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中使用的名称。
正如我所说,这不是最好的方法,因为这个方法与数据库建立了两个连接,而不是一个。所以,如果有人有更好的解决方案,我会接受它!