如何在Slim 4中设置和注入多个PDO数据库连接? - php

我可以创建一个PDO实例并成功注入它。我直接定义了PDO::class,并使用__construct(PDO $pdo)将其注入到构造函数中。我需要像PDO1::classPDO2::class这样的东西来注入它,如下所示:__construct(PDO1 $pdo1, PDO2 $pdo2)但这显然行不通。只有一个PDO类,我需要做的是使用不同数据库凭据的2个实例。
最好的方法是什么?

我像这样通过PDO设置了一个数据库定义,它的工作原理是:

文件:dependencies.php

use DI\ContainerBuilder;
use Psr\Container\ContainerInterface;

return function (ContainerBuilder $containerBuilder) {
    $containerBuilder->addDefinitions([
        PDO::class => function (ContainerInterface $c) {
            $dbSettings = $c->get('settings')['db1'];
            $dsn = 'mysql:host=' . $dbSettings['host'] . ';dbname=' . $dbSettings['dbname'];
            $options = [
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
                PDO::ATTR_EMULATE_PREPARES => false,
            ];
            return new PDO($dsn, $dbSettings['user'], $dbSettings['pass'], $options);
        },
    ]);
};

文件:index.php

...
// Set up dependencies
$dependencies = require __DIR__ . '/../app/dependencies.php';
$dependencies($containerBuilder);
// Build PHP-DI Container instance
$container = $containerBuilder->build();
// Set container to create App with on AppFactory
AppFactory::setContainer($container);
// Instantiate the app
$app = AppFactory::create();
...

文件SomeRepository.php

use PDO;

class SomeRepository{

    protected $pdo;

    public function __construct(PDO $pdo) {
        $this->pdo = $pdo;
    }
}

我在this文章中看到过类似的内容:

return function (ContainerBuilder $containerBuilder) {
    $containerBuilder->addDefinitions([
        'db1' => function (ContainerInterface $c) {
            $db1Settings = $c->get('settings')['db1'];
            $dsn = 'mysql:host=' . $db1Settings['host'] . ';dbname=' . $db1Settings['dbname'];
            $options = [ ... ];
            return new PDO($dsn, $db1Settings['user'], $db1Settings['pass'],$options);
        },
        'db2' => function (ContainerInterface $c) {
            $db2Settings = $c->get('settings')['db2'];
            $dsn = 'mysql:host=' . $db2Settings['host'] . ';dbname=' . $db2Settings['dbname'];
            $options = [ ... ];
            return new PDO($dsn, $db2Settings['user'], $db2Settings['pass'],$options);
        },

    ]);
};

但这是最好的方法吗?以及如何在无需注入整个容器的情况下访问存储库类中的连接?

参考方案

您有多种选择:

连接代理
扩展PDO
自动连线对象

1.连接代理

例:

use PDO;

class ConnectionProxy
{
    private $pdo;

    private $pdo2;

    public function __construct(PDO $pdo, PDO $pdo2)
    {
        $this->pdo = $pdo;
        $this->pdo2 = $pdo2;
    }

    public function getPdo(): PDO
    {
        return $this->pdo;
    }

    public function getPdo2(): PDO
    {
        return $this->pdo2;
    }
}

容器定义:

return [
    ConnectionProxy::class => function (ContainerInterface $c) {
        return new ConnectionProxy(
            $container->get('db1'),
            $container->get('db2')
        );
    },
    'db1' => function (ContainerInterface $container) {
        return new PDO(...);
    },
    'db2' => function (ContainerInterface $container) {
        return new PDO(...);
    },
];

用法

class MyRepository
{
    private $pdo;

    private $pdo2;

    public function __construct(ConnectionProxy $connectionProxy)
    {
        $this->pdo = $connectionProxy->getPdo();
        $this->pdo2 = $connectionProxy->getPdo2();
    }
}

2.扩展PDO

use PDO;

class PDO2 extends PDO
{

}

容器定义:

use PDO2;

// ...

return [
    PDO::class => function (ContainerInterface $container) {
        return new PDO(...);
    },

    PDO2::class => function (ContainerInterface $container) {
        return new PDO2(...);
    },
];

用法

use PDO;
use PDO2;

class MyRepository
{
    private $pdo;

    private $pdo2;

    public function __construct(PDO $pdo, PDO2 $pdo2)
    {
        $this->pdo = $pdo;
        $this->pdo2 = $pdo2;
    }
}

3.自动接线对象

参见Matthieu Napoli的答案:https://stackoverflow.com/a/57758106/1461181

PDO PHP SQLite3数据库连接常规错误14 - php

我有2个sqlite3.x数据库(来自iPhone),一个来自游戏应用程序,另一个是通讯录。我在php conf中记录日志并显示错误“ on”。使用PHP / PDO,我可以显示游戏数据库中的字段和值,包括我在结果页中捕获的图像斑点,并使用“ img src ='data:...”进行渲染。我在其他字段上使用htmlentities捕获plist二进制blo…

PHP:对数组排序 - php

请如何排序以下数组Array ( 'ben' => 1.0, 'ken' => 2.0, 'sam' => 1.5 ) 至Array ( 'ken' => 2.0, 'sam' => 1.5, 'ben' =&…

PHP:不推荐使用password_hash的'salt'选项 - php

我正在使用密码哈希进行注册。我需要手动创建Salt,以下是我使用的代码:$options = [ 'cost' => 11, 'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM) ]; $password = password_hash( $this->…

PHP PDO组按列名称查询结果 - php

以下PDO查询返回以下结果:$db = new PDO('....'); $sth = $db->prepare('SELECT ...'); 结果如下: name curso ABC stack CDE stack FGH stack IJK stack LMN overflow OPQ overflow RS…

PHP-全局变量的性能和内存问题 - php

假设情况:我在php中运行一个复杂的站点,并且我使用了很多全局变量。我可以将变量存储在现有的全局范围内,例如$_REQUEST['userInfo'],$_REQUEST['foo']和$_REQUEST['bar']等,然后将许多不同的内容放入请求范围内(这将是适当的用法,因为这些数据指的是要求自…