Symfony2,动态数据库连接/Doctrine Service 的早期覆盖 [英] Symfony2, Dynamic DB Connection/Early override of Doctrine Service

查看:17
本文介绍了Symfony2,动态数据库连接/Doctrine Service 的早期覆盖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a Core config Database, each row is an 'App' with some basic config etc.
Once you have chosen your app, I want to connect to a database using a property of that row (ID), and the host may also change based on the row.

我想要的是注册一个使用这些详细信息设置 Doctrine 服务的服务,如果您在站点上需要它的位置(我根据 URI 知道该位置).

What I want is to register a service that sets up the Doctrine service using these details if you are in a place on the site that it's required (which I know based on URI).

我正在使用实体管理器和各种 Doctrine 侦听器/事件子

I am using the Entity manager, and various Doctrine Listeners/Event subs

我已经尝试过 ConnectionFactory,但这似乎会导致订阅者出现问题.

I've played around with the ConnectionFactory, but this appears to cause problems with the subscribers.

连接某些东西以透明地修改 Doctrine 服务的最佳方法是什么,以便控制器可以在不知道它们连接到哪个数据库主机和数据库名称的情况下采取行动?

What is the best way to hook something up that will transparently modify the Doctrine service, so that the controllers can act without any knowledge of which DB host and DB name they are connecting to?

这种类型的每个数据库都将具有相同的结构,因此所有实体映射都是正确的.

Each DB of this type will have the same structure so all Entity mapping is correct.

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

I'm looking for a really clean implementation, hopefully using the Service Container to avoid any 'hacks'.

有人知道这样做吗?

推荐答案

这里是新的和改进的非反射版本

Here is the new and improved non-reflection version

#services.yml
acme_app.dynamic_connection:
    class: %acme.dynamic_doctrine_connection.class%
    calls:
        - [setDoctrineConnection, [@doctrine.dbal.default_connection]]


<?php

namespace AcmeBundleAppBundle;

use DoctrineDBALConnection;
use SymfonyComponentHttpKernelExceptionServiceUnavailableHttpException;
use Exception;

class DynamicDoctrineConnection
{
    /**
     * @var Connection
     */
    private $connection;

    /**
     * Sets the DB Name prefix to use when selecting the database to connect to
     *
     * @param  Connection       $connection
     * @return SiteDbConnection $this
     */
    public function setDoctrineConnection(Connection $connection)
    {
        $this->connection = $connection;

        return $this;
    }

    public function setUpAppConnection()
    {
        if ($this->request->attributes->has('appId')) {
            $connection = $this->connection;
            $params     = $this->connection->getParams();

            // we also check if the current connection needs to be closed based on various things
            // have left that part in for information here
            // $appId changed from that in the connection?
            // if ($connection->isConnected()) {
            //     $connection->close();
            // }

            // Set default DB connection using appId
            //$params['host']   = $someHost;
            $params['dbname'] = 'Acme_App'.$this->request->attributes->get('appId');

            // Set up the parameters for the parent
            $connection->__construct(
                $params, $connection->getDriver(), $connection->getConfiguration(),
                $connection->getEventManager()
            );

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

        return $this;
    }
}

这篇关于Symfony2,动态数据库连接/Doctrine Service 的早期覆盖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆