问题描述
我可以创建PDO
的实例并将其成功注入.我直接定义了PDO::class
,并使用__construct(PDO $pdo)
将其注入到构造函数中.我需要像PDO1::class
和PDO2::class
这样的东西来注入它,如下所示:__construct(PDO1 $pdo1, PDO2 $pdo2)
但这显然行不通.只有一个PDO
类,我需要做的是使用不同数据库凭据的2个实例.
最好的方法是什么?
I could make an instance of PDO
and inject it successfully. I defined the PDO::class
directly and injected it in the constructor with __construct(PDO $pdo)
. I would need something like PDO1::class
and PDO2::class
to inject it like follows: __construct(PDO1 $pdo1, PDO2 $pdo2)
but that obviously doesn't work. There is only one PDO
class and what I need to do is 2 instances of it with different database credentials.
What is the best way to do it?
我像这样通过PDO设置了一个数据库定义,它的工作原理是:
I set up one definition of a database via PDO like this and it works:
文件: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;
}
}
我在这篇文章中看到了这样的内容:
I've seen something like this in this article:
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);
},
]);
};
但这是最好的方法吗?以及如何在无需注入整个容器的情况下访问存储库类中的连接?
But is it the best way to do it? And how can I access the connections in a repository class without having to inject the whole container?
推荐答案
您有多种选择:
- 连接代理
- 扩展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
See Matthieu Napoli's answer: https://stackoverflow.com/a/57758106/1461181
这篇关于如何在Slim 4中设置和注入多个PDO数据库连接?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!