小编典典

Symfony2,动态数据库连接/主义服务的早期覆盖

php

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

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

我正在使用实体管理器和各种“教义侦听器/事件”子对象

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

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

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

我正在寻找一个真正干净的实现,希望使用服务容器来避免任何“ hacks”。

有谁知道这样做吗?


阅读 240

收藏
2020-05-29

共1个答案

小编典典

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

#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;
    }
}
2020-05-29