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

我可以创建一个实例PDO并成功注入它。我PDO::class直接定义了并将其注入到构造函数中__construct(PDO $pdo)。我需要类似的东西PDO1::class并按PDO2::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;

    }

}

我在这篇文章中看到过这样的事情:


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

          ]);

};

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


哆啦的时光机
浏览 160回答 2
2回答

当年话下

您有多种选择:扩展 PDO自动装配对象1. 扩展 PDOuse PDO;class PDO2 extends PDO{    // must be empty}容器定义: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;    }}

波斯汪

如果你的应用中有一个类的多个实例(这里你有多个PDO类的实例),那么你必须配置每次注入哪一个。这意味着PDO不能自动装配,因为 PHP-DI 无法根据服务/控制器/等来决定您想要哪个实例。您需要使用配置(请参阅http://php-di.org/doc/php-definitions.html#autowired-objects)来定义为每个服务注入哪个实例(db1或db2在您的示例中)。return [    MyService::class => DI\autowire()        ->constructorParameter('pdo', DI\get('db1'))        ->constructorParameter('pdo2', DI\get('db2')),    'db1' => function (ContainerInterface $c) {        return new PDO();    },    'db2' => function (ContainerInterface $c) {        return new PDO();    },];
打开App,查看更多内容
随时随地看视频慕课网APP