Symfony2 - 运行时动态生成Doctrine数据库连接

12

我正在寻找在Symfony中利用Doctrine进行实体管理的数据库即时连接的良好解决方案。

我的情景是,所有访问我们服务的用户将访问*.website.com地址,例如client1.website.com。

我们希望使用一个Doctrine实体来为客户端表(Client table)查找他们的数据库凭证,并根据其账户URL动态更改数据库凭证。

到目前为止,我在stackoverflow上找到了以下讨论动态更改数据库凭证的主题-但没有明确的可行解决方案。

我想提出合作,共同制定一个可行的解决方案,并为其他想要修改Symfony中数据库连接参数的人编写博客/教程文章。

这里是一些相关的帖子:

Dynamic database connection symfony2

Symfony2, Dynamic DB Connection/Early override of Doctrine Service

谢谢!

2个回答

17

如果$em是一个已经存在的实体管理器且您想要重用它的配置,则可以使用以下代码:

$conn = array(
    'driver'   => 'pdo_mysql',
    'user'     => 'root',
    'password' => '',
    'dbname'   => 'foo'
);

$new = \Doctrine\ORM\EntityManager::create(
    $conn,
    $em->getConfiguration(),
    $em->getEventManager()
);

我想要做的是永久性地改变所有实体在任何地方使用的数据库信息。看起来,使用这种方法每次使用它都会打开多个数据库连接? - Scott R.
你可以将其实现为Singleton,这样你就总是只会得到一个实例。 - Michał Pipa
这个功能非常棒,可以在运行时动态连接到多个数据库!太厉害了! - Scott R.
我对Doctrine/Symfony2非常陌生,但在其他方面很老练,所以请原谅我的失误。这个解决方案是否意味着,如果我有多个数据库,所有数据库共享相同的模式(例如,每个大型项目都有不同的数据集,但它们的结构相同),那么一旦用户进行身份验证并选择了项目,我就可以切换到所选的数据库???如果是这样,那就正是我想要的。 - Radiotrib

9

我需要做类似的事情 - 运行时发现可用的数据库服务器。我通过覆盖 doctrine.dbal.connection_factory.class 参数并替换自己派生的Doctrine Bundle的 ConnectionFactory 类来实现它。

我的services.yml提供了该参数,指向我的自定义类。

parameters:
     doctrine.dbal.connection_factory.class: Path\To\Class\CustomConnectionFactory

然后,在Path\To\Class\CustomConnectionFactory.php中填写您的发现逻辑。

<?php

namespace Path\To\Class;

use Doctrine\Bundle\DoctrineBundle\ConnectionFactory;
use Doctrine\Common\EventManager;
use Doctrine\DBAL\Configuration;

class CustomConnectionFactory extends ConnectionFactory 
{

    public function createConnection(array $params, Configuration $config = null, EventManager $eventManager = null, array $mappingTypes = array())
    {
        // Discover and override $params array here.
        // A real-world example might obtain them from zookeeper,
        // consul or etcd for example. You'll probably want to cache
        // anything you obtain from such a service too.

        $params['driver'] = 'pdo_mysql';
        $params['host'] = '10.1.2.3';
        $params['port'] = 3306;
        $params['dbname'] = 'foo';
        $params['user'] = 'myuser';
        $params['password'] = 'mypass';

        //continue with regular connection creation using new params
        return parent::createConnection($params, $config, $eventManager,$mappingTypes);
    }

}

请注意,Symfony 3.2具有在容器配置中使用环境变量并根据需要使用它们的功能(而不是在编译容器时固定它们的值)。有关更多详细信息,请参见博客公告

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