Symfony2, Dynamic DB Connection/Early override of Doctrine Service

前端 未结 5 2039
别那么骄傲
别那么骄傲 2020-11-29 04:24

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

5条回答
  •  离开以前
    2020-11-29 04:52

    Combined, these two postings helped me solve my own very similar problem. Here is my solution, maybe it is useful for someone else:

    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
                    }
                }
            }
        }
    }
    

    To get this to work, I set up services.yml as follows:

    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 }
    

    and I have this routing configuration to get the _site parameter, which in my case is part of the URL, but you can probably get it in other ways depending on your setup:

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

提交回复
热议问题