在 Symfony2 中的每个请求之前动态设置 Doctrine EntityManager 连接



我正在开发一个Symfony2站点,该站点将托管许多站点,每个站点都有自己的数据库。我已经实现了一项使用反射来更改"客户端"实体管理器上的连接参数(用户名、密码、数据库名称)的服务。我不确定如何在 FOSUserBundle 调用其身份验证服务之前触发此服务。我尝试创建一个 Symfony2 请求事件侦听器,但这似乎不起作用:

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 DoctrineBundleDoctrineBundleRegistry */
    $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 使用的实体管理器吗?

您必须在任何

内核事件之前拥有它。也许最好的地方是把它放在你的应用程序内核(app/AppKernel.php)本身的某个地方。

你可以把它带到getBundles(),或者添加类似的东西:

public function boot() {
    parent::boot();
    resetClientEntityManager();
}

我还没有测试过,但它应该可以解决问题。 boot() 是初始化容器的函数,因此您应该在容器初始化后立即进行切换,然后其他任何事情都有机会做任何事情。

相关内容

  • 没有找到相关文章

最新更新