Symfony2动态数据库连接使用Doctrine

3
我尝试在Symfony 2中使用doctrine拥有多个数据库连接,但无法做到。
我在谷歌和stackoverflow上进行了广泛搜索,但无论哪里,都是通过config.yml文件或动态数据库完成的,其中所有数据库具有相同的架构/实体。
但是对于我的情况来说,数据库是基于子域确定的,并且并非所有子域的数据库架构都相同。
例如: test1.example.com => 应加载test1数据库 test2.example.com => 将加载test2数据库
test1和test2数据库都不同,都是在数据库级别创建的,而doctrine中没有实体项。
请问有谁能帮助我在Symfony 2中如何实现这一点?

你是否尝试在不创建Doctrine实体的情况下完成这个任务?如果是,那么实体对象是如何被管理的? - geoB
是的,我不会创建Doctrine条目,因为我事先不知道模式/表结构。表和数据库名称已知,但表字段可能会被子域的管理员更改/删除/修改。例如:test3.example.com的管理员将添加字段/自定义表格,这些都是直接使用SQL完成的。之后,test3.example.com的其他用户将使用这些表。我知道我可以直接使用SQL查询,但这会在编码中造成混乱,因为我必须处理所有内容:(希望在Doctrine + Symfony 2中有某种方法。 - adithyau
即使为每个新的数据库创建Doctrine实体,也会导致更多问题,因为Doctrine实体依赖于物理文件,这对SAAS环境非常不利:(特别是在AWS中根据负载自动扩展/缩小时) - adithyau
2个回答

12

在我看来,使用Doctrine ODM不是正确的方法。您仍然可以使用Doctrine连接到数据库并查询它们。但是,如果您没有实体类,则使用实体管理器似乎是不合适的。

使用Doctrine进行连接处理

以下是使用Doctrine Connection类创建到数据库的连接的方法:

/** @var \Doctrine\Bundle\DoctrineBundle\ConnectionFactory $connectionFactory */
$connectionFactory = $this->getContainer()->get('doctrine.dbal.connection_factory');
$connection = $connectionFactory->createConnection(
    array('pdo' => new \PDO("mysql:host=$hostname;dbname=$dbname", $username, $password))
);

现在,您可以将$connection用作简单的PDO对象:

$connection->executeQuery('SELECT * FROM your_table');

您可以将此代码添加为“服务”,以便随时随地访问它。
如果您想连接到不同的数据库以供不同的域使用,则可以使用此代码来识别域:
$this->getRequest()->getHost();

要在一个操作中访问域,请执行以下操作:
public function yourAction(Request $request, /* ... */)
{
    // the Controller extends the Container. So need to get it here:
    $connectionFactory = $this->get('doctrine.dbal.connection_factory');

    // also access the domain like this:
    $domain = $request->getHost();
}

谢谢你的帮助。我尝试了相同的方法但失败了。:( 我发现$this->getContainer()在控制器中不可用。我搜索了一下,发现必须在服务中完成。我也这样做了。创建了一个服务并添加了代码,但仍然无法工作。我参考了http://forum.symfony-project.org/viewtopic.php?t=41082&p=132396来创建一个服务。你能帮我吗?我们应该在哪里编写getContainer()代码以及如何在我们的控制器中使用它们。 - adithyau
我已经添加了一个示例,演示如何在控制器中访问“Request”对象。 - ferdynator
很高兴我能帮到你。 - ferdynator

2

感谢byf-ferdy (https://dev59.com/xXnZa4cB1Zd3GeqPw_x9#20444097),我能够找出如何在没有Doctrine实体的情况下使用其他数据库。只需在您的操作控制器中使用以下代码即可:

$connectionFactory = $this->get('doctrine.dbal.connection_factory');                
$connection = $connectionFactory->createConnection(
                array('pdo' => new \PDO("mysql:host=$hostname;dbname=$dbname", 
                       $username,$password))
 );
 $query = $connection->executeQuery('SELECT * FROM multi_client');
 $results = $query->fetchAll();

如果想知道访问的子域名,可以使用以下代码:

$domain = $request->getHost();

因此,可以更改数据库名称和其他参数。

希望这对其他人有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接