php – Symfony2,动态数据库连接/ Doctrine Service的早期覆盖

我有一个核心配置数据库,每行都是一个带有一些基本配置等的“应用程序”.
一旦选择了应用程序,我想使用该行的属性(ID)连接到数据库,主机也可能会根据行进行更改.

我想要的是注册一个服务,使用这些详细信息设置Doctrine服务,如果你在网站上的所需位置(我知道基于URI).

我正在使用实体管理器和各种Doctrine Listeners / Event subs

我玩过ConnectionFactory,但这似乎会导致订阅者出现问题.

什么是挂钩的最佳方法,它将透明地修改Doctrine服务,以便控制器可以在不知道他们连接到哪个数据库主机和数据库名称的情况下执行操作?

此类型的每个DB都具有相同的结构,因此所有实体映射都是正确的.

我正在寻找一个非常干净的实现,希望使用服务容器来避免任何’黑客攻击’.

有没有人知道这样做?

最佳答案
结合起来,这两个帖子帮助我解决了我自己非常相似的问题.这是我的解决方案,也许对其他人有用:

<?php

namespace Calitarus\CollaborationBundle\EventListener;

use Symfony\Component\HttpFoundation\Request;
use Doctrine\DBAL\Connection;
use Exception;
use Monolog\Logger;



class DatabaseSwitcherEventListener {

    private $request;
    private $connection;
    private $logger;

    public function __construct(Request $request, Connection $connection, Logger $logger) {
        $this->request = $request;
        $this->connection = $connection;
        $this->logger = $logger;
    }


    public function onKernelRequest() {
        if ($this->request->attributes->has('_site')) {
            $site = $this->request->attributes->get('_site');

            $connection = $this->connection;
            $params     = $this->connection->getParams();

            $db_name = 'br_'.$this->request->attributes->get('_site');
            // TODO: validate that this site exists
            if ($db_name != $params['dbname']) {
                $this->logger->debug('switching connection from '.$params['dbname'].' to '.$db_name);
                $params['dbname'] = $db_name;
                if ($connection->isConnected()) {
                    $connection->close();
                }
                $connection->__construct(
                    $params, $connection->getDriver(), $connection->getConfiguration(),
                    $connection->getEventManager()
                );

                try {
                    $connection->connect();
                } catch (Exception $e) {
                    // log and handle exception
                }
            }
        }
    }
}

为了使这个工作,我设置services.yml如下:

services:
    cc.database_switcher:
        class:      Calitarus\CollaborationBundle\EventListener\DatabaseSwitcherEventListener
        arguments:  [@request, @doctrine.dbal.default_connection, @logger]
        scope:      request
        tags:
            - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }

我有这个路由配置来获取_site参数,在我的情况下,它是URL的一部分,但您可以通过其他方式获取它,具体取决于您的设置:

resource: "@CCollabBundle/Controller"
type:     annotation
prefix:   /{_site}
defaults:
 _site: default

转载注明原文:php – Symfony2,动态数据库连接/ Doctrine Service的早期覆盖 - 代码日志