У меня есть две базы данных: одна для производства, а другая - для резервного копирования. Я хочу иметь службу в Symfony, вызываемую из команды, которая может выполнять некоторые SQL-запросы в одной из этих двух баз данных в зависимости от имени соединения, переданного командой. Проблема в том, что я не знаю, как получить соединение DBAL, используя имя соединения в качестве параметра.
Я использую Symfony 3.4.
Config.yml:
#config.yml
doctrine:
dbal:
default_connection: prod
connections:
prod:
driver: '%database_driver1%'
host: '%database_host1%'
port: '%database_port1%'
dbname: '%database_name1%'
user: '%database_user1%'
password: '%database_password1%'
charset: UTF8
backup:
driver: '%database_driver2%'
host: '%database_host2%'
port: '%database_port2%'
dbname: '%database_name2%'
user: '%database_user2%'
password: '%database_password2%'
charset: UTF8
Идея Mi имеет такую услугу:
<?php
namespace ErqBundle\Services;
use Doctrine\DBAL\Driver\Connection;
class ProcSQL {
public function exSQL($conn_name)
{
// How to obtain the connection ????
$conn=$this->getDoctrine()->getConnection($conn_name);
// This doesn't work !!!
$sql = "SELECT ....";
$stmt = $conn->query($sql);
}
}
Но мне не удалось получить соединение с именем соединения, например "prod" или "backup" (что-то вроде: $ conn = $ this-> getDoctrine () -> getConnection ($ conn_name))
Единственный способ, которым я заставил это работать, - это снова определить параметры соединения и сделать соединение следующим образом:
public function exSQL()
{
$config = new \Doctrine\DBAL\Configuration();
$connectionParams = array(
'dbname' => 'dbname',
'user' => 'user',
'password' => 'password',
'host' => 'prod_host',
'driver' => 'pdo_mysql',
);
$conn = \Doctrine\DBAL\DriverManager::getConnection($connectionParams, $config);
$sql = "SELECT ...";
$stmt = $conn->query($sql);
while ($row = $stmt->fetch()) {
var_dump($row);
}
// This works !!!
}
Заранее спасибо.






Вы можете использовать инъекцию зависимостей следующим образом:
use \Doctrine\ORM\EntityManager;
class ProcSQL {
private $entityManager
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
public function exSQL($conn_name)
{
$conn = $this->entityManager->getConnection($conn_name);
}
}
Вам нужно объявить свой сервис следующим образом (я не знаю, используете ли вы автоподключение или нет):
ErqBundle\Services\ProcSql:
class: ErqBundle\Services\ProcSql
arguments:
- '@doctrine.orm.entity_manager'
Если у вас есть доступ к доктрине, вы можете сделать что-то вроде
$this->getDoctrine()->getManager('backup');
Но, как говорит @AlessandroMinoccheri, лучше вводить его / их напрямую.
Если вам нужно ввести значение по умолчанию, просто используйте doctrine.orm.entity_manager, если вам нужно ввести backup, используйте doctrine.orm.backup_entity_manager
У меня нет доступа к Доктрине. Я внутри службы и не знаю, как получить доступ к доктрине. Я получаю эту ошибку: Попытка вызвать неопределенный метод с именем «getDoctrine» класса «ErqBundle \ Services \ ProcSQL».
Спасибо вам обоим. Размышляя над вашими ответами, я пробовал:
Я добавил:
use \Doctrine\ORM\EntityManager;
и вызвал Doctrine EntityManager непосредственно в методе конструкции.
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
public function exSQL($conn_name)
{
$conn = $this->entityManager->getConnection($conn_name);
$sql = "SELECT ...";
$stmt = $conn->query($sql);
while ($row = $stmt->fetch()) {
var_dump($row);
}
}
и работает !!!!!
Большое спасибо!!!
Автовайн не использую. Я получаю эту ошибку: Catchable Fatal Error: Аргумент 1, переданный в ErqBundle \ Services \ ProcSQL :: __ construct (), должен быть экземпляром ErqBundle \ Services \ EntityManager, заданным экземпляром Doctrine \ ORM \ EntityManager. Я определил сервис внутри de Bundle ErqBundle