我有一个简单的Symfony2应用程序,需要根据子域连接到特定的数据库。数据库名称与子域名相同。
域:alpha.example.com
- 数据库名称:alpha
域:beta.example.com
- 数据库名称:beta
在我看来,实现此目的的最简单方法是将当前子域传递到config.yml
文件中
#config.yml
doctrine:
dbal:
driver: "%database_driver%"
host: "%database_host%"
port: "%database_port%"
dbname: "current-subdomain-name-here"
user: "%database_user%"
password: "%database_password%"
问题是如何在config.yml
中传递和访问当前的子域名?
我会避免把它放到app.php
.也许您还需要相同的代码app_dev.php
用于开发和测试。
每个子域一个配置文件看起来也不是很方便。
看看:
http://symfony.com/doc/current/cookbook/configuration/external_parameters.html#miscellaneous-configuration
在那里你可以做一些类似的事情(未经测试):
# app/config/config.yml
imports:
- { resource: parameters.php }
-
// app/config/parameters.php
$subdomain = array_shift((explode(".",$_SERVER['HTTP_HOST'])));
$container->setParameter('doctrine.dbal.dbname', $subdomain);
这是不可能的,但无论如何,配置文件不应该包含任何应用程序逻辑。
您可以按照说明书中解释的有关多个管理器和连接的指令进行操作,然后创建逻辑(例如使用依赖注入服务),但实现取决于您的特定用例,对此我一无所知。
你不会想在config.yml中这样做。 相反,您应该挂钩到内核请求并在那里设置连接。 查看这篇文章的接受答案:
Symfony2,动态数据库连接/Doctrine Service 的早期覆盖
然后,您可以在侦听器中使用$this->request->getHost()
,解析子域,并在将子域的名称作为dbname
参数传递后打开与数据库的连接。 例如(未测试):
public function onKernelRequest()
{
// this might cause issues if there is no subdomain, might need regex...just an example
$dbname = array_shift(explode('.', $this->request->getHost()));
$params = $this->connection->getParams();
if ($dbname !== $params['dbname'])
{
$this->connection->close();
$this->connection = new Connection()
$params,
$this->connection->getDriver(),
$this->connection->getConfiguration(),
$this->connection->getEventManager()
);
try {
$this->connection->connect();
} catch (Exception $e) {
// log and handle exception
}
}
}
解决了自己的挑战。
我为每个子域创建了不同的配置文件。就我而言,我的子域数量有限。
#config.yml
doctrine:
dbal:
driver: "%database_driver%"
host: "%database_host%"
port: "%database_port%"
user: "%database_user%"
password: "%database_password%"
子域alpha.example.com
的配置:
#config_alpha.yml
doctrine:
dbal:
dbname: "alpha"
子域beta.example.com
的配置:
#config_beta.yml
doctrine:
dbal:
dbname: "beta"
在app.php
中,我们确定子域,并加载相应的配置:
// web/app.php
// ...
$subdomain = array_shift((explode(".",$_SERVER['HTTP_HOST'])));
// In case of alpha.example.com
// $subdomain = "alpha"
// Its going to load config_alpha.yml
$kernel = new AppKernel($subdomain, true);
// ...