我正在开发一个将托管多个站点的Symfony2站点,每个站点都有自己的数据库。我已经实现了一个服务使用反射来更改'客户端'实体管理器上的连接参数(用户名,密码,dbname)。在FOSUserBundle调用其身份验证服务之前,我不确定如何触发此服务。我试图创建一个Symfony2 Request事件监听器,但这似乎不起作用:
class RequestListener {
private $clientSiteContext;
function __construct($clientSiteContext) {
$this->clientSiteContext = $clientSiteContext;
}
public function onKernelRequest(GetResponseEvent $event) {
if ($event->getRequestType() == HttpKernel::MASTER_REQUEST) {
$this->clientSiteContext->resetClientEntityManager();
}
}
}
resetClientEntityManager()实现
public function resetClientEntityManager() {
/** @var $doctrine \Doctrine\Bundle\DoctrineBundle\Registry */
$doctrine = $this->container->get('doctrine');
$dbConfig = $this->getConnectionParams();
$dbalServiceName = sprintf('doctrine.dbal.%s_connection', 'client');
$clientEmName = 'client';
$connection = $this->container->get($dbalServiceName);
$connection->close();
$refConn = new \ReflectionObject($connection);
$refParams = $refConn->getProperty('_params');
$refParams->setAccessible('public');
$params = $refParams->getValue($connection);
$params['dbname'] = $dbConfig['dbname'];
$params['user'] = $dbConfig['user'];
$params['host'] = $dbConfig['host'];
$params['password'] = $dbConfig['password'];
$params['driver'] = $dbConfig['driver'];
$params['charset'] = 'UTF8';
$refParams->setAccessible('private');
$refParams->setValue($connection, $params);
$doctrine->resetEntityManager($clientEmName);
}
有人可以建议我如何让这个侦听器为每个页面请求调用一次,并且它会影响FOSUserBundle使用的实体管理器吗?
答案 0 :(得分:2)
你必须在任何内核事件之前拥有它。可能最好的地方就是把它放在AppKernel(app/AppKernel.php
)本身的某个地方。
你可以把它带到getBundles(),或添加类似的东西:
public function boot() {
parent::boot();
resetClientEntityManager();
}
我没有测试过,但它应该可以解决问题。 boot()是容器初始化的函数,所以你应该在容器初始化之后立即进行切换,之后其他任何东西都有可能做任何事情。