Combined, these two postings helped me solve my own very similar problem. Here is my solution, maybe it is useful for someone else:
<?php
namespace CalitarusCollaborationBundleEventListener;
use SymfonyComponentHttpFoundationRequest;
use DoctrineDBALConnection;
use Exception;
use MonologLogger;
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
}
}
}
}
}
To get this to work, I set up services.yml as follows:
services:
cc.database_switcher:
class: CalitarusCollaborationBundleEventListenerDatabaseSwitcherEventListener
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
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…