В моем проекте Symfony 3.4 я получил несколько баз данных, которые управляются одним менеджером сущностей.Рассмотрим следующий код:
config.yml
doctrine:
dbal:
default_connection: default
connections:
dynamic:
driver: pdo_mysql
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name_dynamic%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
wrapper_class: 'AppBundle\Connection\ConnectionWrapper'
orm:
default_entity_manager: default
auto_generate_proxy_classes: "%kernel.debug%"
entity_managers:
dynamic:
connection: dynamic
auto_mapping: false
mappings:
DynamicBundle: ~
naming_strategy: doctrine.orm.naming_strategy.underscore
AppBundle \ Connection \ ConnectionWrapper
<?php
namespace AppBundle\Connection;
use Doctrine\DBAL\Connection;
use Symfony\Component\HttpFoundation\Session\Session;
use Doctrine\Common\EventManager;
use Doctrine\DBAL\Events;
use Doctrine\DBAL\Event\ConnectionEventArgs;
use Doctrine\DBAL\Driver;
class ConnectionWrapper extends Connection
{
/**
* @var array
*/
private $params = [];
/**
* @var bool
*/
private $_isConnected = false;
public function __construct(array $params, Driver $driver, $config, $eventManager)
{
$this->params['dbname'] = $params['dbname'];
$this->params['user'] = $params['user'];
$this->params['password'] = $params['password'];
parent::__construct($params, $driver, $config, $eventManager);
}
public function forceSwitch($dbName, $dbUser, $dbPassword)
{
$this->params['dbname'] = $dbName;
$this->params['user'] = $dbUser;
$this->params['password'] = $dbPassword;
if ($this->isConnected()) {
$this->close();
}
}
/**
* {@inheritDoc}
*/
public function connect()
{
if ($this->isConnected()) {
return true;
}
$driverOptions = isset($params['driverOptions']) ? $params['driverOptions'] : array();
$params = $this->getParams();
$params['dbname'] = $this->params['dbname'];
$this->_conn = $this->_driver->connect($params, $this->params['user'], $this->params['password'], $driverOptions);
if ($this->_eventManager->hasListeners(Events::postConnect)) {
$eventArgs = new ConnectionEventArgs($this);
$this->_eventManager->dispatchEvent(Events::postConnect, $eventArgs);
}
$this->_isConnected = true;
return true;
}
/**
* {@inheritDoc}
*/
public function isConnected()
{
return $this->_isConnected;
}
/**
* {@inheritDoc}
*/
public function close()
{
if ($this->isConnected()) {
parent::close();
$this->_isConnected = false;
}
}
}
Services.yml
app.handler.session_idle:
class: AppBundle\EventListener\RequestListener
arguments: ["@doctrine.orm.dynamic_entity_manager"]
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
AppBundle \ EventListener \ RequestListener
namespace AppBundle\EventListener;
use Doctrine\ORM\EntityManager;
class RequestListener{
protected $entityManager;
public function __construct(EntityManager $entityManager){
EntityManager $entityManager
}
public function onKernelRequest(GetResponseEvent $event){
$em = $this->entityManager;
}
}
Цель класса ConnectionWrapper
- переключение базы данных после загрузки приложения в зависимости отпользователь вошел в систему (каждый пользователь имеет свою собственную БД).
Но когда я пытаюсь загрузить свое приложение с помощью dynamic_entity_Manager
, я получаю следующую ошибку:
Uncaught PHP Exception Doctrine\DBAL\Exception\ConnectionException: "An exception occurred in driver: SQLSTATE[HY000] [1045] Access denied for user ''@'192.168.208.1' (using password: NO)" at /var/www/html/public/dev/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php line 93
Если я использую default entity manager
все отлично работает, даже dynamic entity manager
доступно.Любые идеи, как исправить ошибку, будут приветствоваться.Спасибо.
UPD_1
В ЭТОМ вопрос, как говорят, вводит Doctrine\Common\Persistence\ManagerRegistry
, но мне нужно поместить его в services.yml
декларация.Есть идеи как это сделать?Спасибо.