Symfony 3.4 和 Doctrine:如何使用连接名称从服务内部获取 config.yml 中定义的连接

问题描述 投票:0回答:4

我有两个数据库,一个用于生产,一个用于备份。我想在 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 symfony doctrine symfony-3.4
4个回答
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'

2
投票

谢谢你们俩。思考我尝试过的你的答案:

我补充:

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

} 

并且它有效!!!!

非常感谢!


1
投票

2023 年最好的方法是正确输入提示连接。

自动装配多个连接

您可以通过类型提示您的服务来自动连接不同的连接 具有以下语法的参数:Doctrine\DBAL\Connection $连接。例如,要注入一个连接 名称purchase_logs使用这个:

public function __construct(Connection $purchaseLogsConnection)
{
    $this->connection = $purchaseLogsConnection;
}

就您的情况而言,这将导致:

private $prodConnection;
private $backupConnection;

public function __construct(Connection $prodConnection, Connection $backupConnection)
{
    $this->prodConnection= $prodConnection;
    $this->backupConnection= $backupConnection;
}

public function exSQL() {
    $conn = $this->prodConnection;
    // $conn = $this->backupConnection;
    
    $sql = 'SELECT * FROM ...';
    $stmt = $conn->prepare($sql);
    $stmt->execute();
}

文档:自动装配多个连接


0
投票

如果你有机会接触教义,你可以做类似的事情

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

但正如 @AlessandroMinoccheri 所说,最好直接注入它/它们。

如果需要注入默认的,就用

doctrine.orm.entity_manager
,如果需要注入
backup
,就用
doctrine.orm.backup_entity_manager

© www.soinside.com 2019 - 2024. All rights reserved.