Symfony 3.4 и Doctrine: как я могу получить соединения, определенные в config.yml, изнутри службы, используя имя соединения

У меня есть две базы данных: одна для производства, а другая - для резервного копирования. Я хочу иметь службу в 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 !!!


}

Заранее спасибо.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
0
2 207
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Вы можете использовать инъекцию зависимостей следующим образом:

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'

Автовайн не использую. Я получаю эту ошибку: Catchable Fatal Error: Аргумент 1, переданный в ErqBundle \ Services \ ProcSQL :: __ construct (), должен быть экземпляром ErqBundle \ Services \ EntityManager, заданным экземпляром Doctrine \ ORM \ EntityManager. Я определил сервис внутри de Bundle ErqBundle

John A. 22.05.2018 10:41

Если у вас есть доступ к доктрине, вы можете сделать что-то вроде

$this->getDoctrine()->getManager('backup');

Но, как говорит @AlessandroMinoccheri, лучше вводить его / их напрямую.

Если вам нужно ввести значение по умолчанию, просто используйте doctrine.orm.entity_manager, если вам нужно ввести backup, используйте doctrine.orm.backup_entity_manager

У меня нет доступа к Доктрине. Я внутри службы и не знаю, как получить доступ к доктрине. Я получаю эту ошибку: Попытка вызвать неопределенный метод с именем «getDoctrine» класса «ErqBundle \ Services \ ProcSQL».

John A. 22.05.2018 10:54

Спасибо вам обоим. Размышляя над вашими ответами, я пробовал:

Я добавил:

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);
    }   

} 

и работает !!!!!

Большое спасибо!!!

Другие вопросы по теме