Symfony2,动态数据库连接/提示覆盖原则服务 [英] Symfony2, Dynamic DB Connection/Early override of Doctrine Service

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

问题描述

我有一个核心配置数据库,每行都是一个应用程序与一些基本的配置等。

一旦您选择了您的应用程序,我想使用该行的属性连接到一个数据库(ID),主机也可能根据该行进行更改。



我想要的是注册使用这些详细信息设置Doctrine服务的服务,如果您是在网站上的某个地方(我根据URI知道)。



我正在使用实体管理器,以及各种原则侦听器/事件消息>

我已经使用了ConnectionFactory,但这似乎会导致订阅者出现问题。



什么是最好的方法来勾画一些可以透明地修改Doctrine服务的方法,以便控制器可以在不知道连接到哪个DB主机和数据库名称的情况下进行操作?



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



我是looki有一个真正干净的实现,希望使用服务容器来避免任何黑客。



有没有人知道这样做?

解决方案

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

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


<?php

命名空间Acme\Bundle\AppBundle;

使用Doctrine\DBAL\Connection;
使用Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
使用异常;

class DynamicDoctrineConnection
{
/ **
* @var连接
* /
private $ connection;

/ **
*设置选择数据库连接到
*
* @param时使用的DB名称前缀连接$连接
* @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();

//我们还检查当前连接是否需要根据各种各样的东西
//已经留下了这个信息
// $ appId从那里更改在连接?
// if($ connection-> isConnected()){
// $ connection-> close();
//}

//使用appId设置默认的数据库连接
// $ params ['host'] = $ someHost;
$ params ['dbname'] ='Acme_App'。$ this-> request-> attributes-> get('appId');

//设置父
$ connection-> __构造的参数(
$ params,$ connection-> getDriver(),$ connection-> getConfiguration (),
$ connection-> getEventManager()
);

try {
$ connection-> connect();
} catch(Exception $ e){
//日志和句柄异常
}
}

return $ this;
}
}


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.

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).

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

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

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'.

Does anyone have any knowledge of doing this?

解决方案

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 Acme\Bundle\AppBundle;

use Doctrine\DBAL\Connection;
use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
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,动态数据库连接/提示覆盖原则服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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