如何在 Slim 4 中注入多个 PDO 实例
How to inject multiple PDO instances in Slim 4
我刚刚开始使用 Slim 4(对 Slim 来说也是全新的),在阅读并关注了一些文章之后,我设法获得了一个骨架应用程序设置,其中包含与数据库的 PDO 连接。
我现在正在寻求注入第二个 PDO 实例,以便可以根据请求使用第二个数据库,尽管我正在努力思考如何做到这一点。
我当前的设置是:
settings.php
$settings['db'] = [
'driver' => 'mysql',
'host' => 'database',
'username' => 'root',
'database' => 'demo',
'password' => 'password',
'flags' => [
// Turn off persistent connections
PDO::ATTR_PERSISTENT => false,
// Enable exceptions
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
// Emulate prepared statements
PDO::ATTR_EMULATE_PREPARES => true,
// Set default fetch mode to array
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
],
];
container.php
return [
Configuration::class => function () {
return new Configuration(require __DIR__ . '/settings.php');
},
App::class => function (ContainerInterface $container) {
AppFactory::setContainer($container);
$app = AppFactory::create();
return $app;
},
PDO::class => function (ContainerInterface $container) {
$config = $container->get(Configuration::class);
$host = $config->getString('db.host');
$dbname = $config->getString('db.database');
$username = $config->getString('db.username');
$password = $config->getString('db.password');
$dsn = "mysql:host=$host;dbname=$dbname;";
return new PDO($dsn, $username, $password);
},
];
存储库中的示例用法
class UserReaderRepository
{
/**
* @var PDO The database connection
*/
private $connection;
/**
* Constructor.
*
* @param PDO $connection The database connection
*/
public function __construct(PDO $connection)
{
$this->connection = $connection;
}
/**
* Get user by the given user id.
*
* @throws DomainException
*
* @return array The user data
*/
public function getUsers(): array
{
$sql = "SELECT user_id, title, firstname, surname, email_address FROM user us;";
$statement = $this->connection->prepare($sql);
$statement->execute();
据我所知,PDO class 本身在 container.php
中实例化 - 我如何修改它以实例化 2 个单独的 PDO classes - 我如何稍后在存储库中使用它们?
为清楚起见,我尝试查看 but I don't quite understand where to define the PDO classes. I've also looked here,但似乎没有帮助 - 我没有 dependencies.php
,最接近的是 middleware.php
,但是当我尝试这个时,我收到错误 Uncaught Error: Cannot use object of type DI\Container as array in /var/www/config/middleware.php
:
return function (App $app) {
// Parse json, form data and xml
$app->addBodyParsingMiddleware();
// Add global middleware to app
$app->addRoutingMiddleware();
$container = $app->getContainer();
// PDO database library
$container['db'] = function ($c) {
$settings = $c->get('settings')['db'];
$pdo = new PDO("mysql:host=" . $settings['host'] . ";dbname=" . $settings['dbname'],
$settings['user'], $settings['pass']);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
return $pdo;
};
// Error handler
$settings = $container->get(Configuration::class)->getArray('error_handler_middleware');
$display_error_details = (bool)$settings['display_error_details'];
$log_errors = (bool)$settings['log_errors'];
$log_error_details = (bool)$settings['log_error_details'];
$app->addErrorMiddleware($display_error_details, $log_errors, $log_error_details);
};
经过深思熟虑,我想我已经解决了。
我使用容器创建了 PDO 实例
$container = $app->getContainer();
$container->set('db', function(ContainerInterface $c) {
$config = $c->get(Configuration::class);
$host = $config->getString('db.host');
$dbname = $config->getString('db.database');
$username = $config->getString('db.username');
$password = $config->getString('db.password');
$dsn = "mysql:host=$host;dbname=$dbname;";
return new PDO($dsn, $username, $password);
});
$container->set('db_readonly', function(ContainerInterface $c) {
$config = $c->get(Configuration::class);
$host = $config->getString('db_readonly.host');
$dbname = $config->getString('db_readonly.database');
$username = $config->getString('db_readonly.username');
$password = $config->getString('db_readonly.password');
$dsn = "mysql:host=$host;dbname=$dbname;";
return new PDO($dsn, $username, $password);
});
然后更改存储库以在构造函数中使用 App,然后使用容器获取 PDO 实例
/**
* @var PDO The database
*/
private $db;
/**
* @var PDO The readonly database
*/
private $readonly_db;
/**
* Constructor.
*
* @param App $app The database db
*/
public function __construct(App $app)
{
$container = $app->getContainer();
$this->db = $container->get('db');
$this->readonly_db = $container->get('db_readonly');
}
留在这里以防其他人遇到问题,尽管如果有更好的方法,或者可以改进我当前的方法,我将不胜感激反馈
我刚刚开始使用 Slim 4(对 Slim 来说也是全新的),在阅读并关注了一些文章之后,我设法获得了一个骨架应用程序设置,其中包含与数据库的 PDO 连接。
我现在正在寻求注入第二个 PDO 实例,以便可以根据请求使用第二个数据库,尽管我正在努力思考如何做到这一点。
我当前的设置是:
settings.php
$settings['db'] = [
'driver' => 'mysql',
'host' => 'database',
'username' => 'root',
'database' => 'demo',
'password' => 'password',
'flags' => [
// Turn off persistent connections
PDO::ATTR_PERSISTENT => false,
// Enable exceptions
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
// Emulate prepared statements
PDO::ATTR_EMULATE_PREPARES => true,
// Set default fetch mode to array
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
],
];
container.php
return [
Configuration::class => function () {
return new Configuration(require __DIR__ . '/settings.php');
},
App::class => function (ContainerInterface $container) {
AppFactory::setContainer($container);
$app = AppFactory::create();
return $app;
},
PDO::class => function (ContainerInterface $container) {
$config = $container->get(Configuration::class);
$host = $config->getString('db.host');
$dbname = $config->getString('db.database');
$username = $config->getString('db.username');
$password = $config->getString('db.password');
$dsn = "mysql:host=$host;dbname=$dbname;";
return new PDO($dsn, $username, $password);
},
];
存储库中的示例用法
class UserReaderRepository
{
/**
* @var PDO The database connection
*/
private $connection;
/**
* Constructor.
*
* @param PDO $connection The database connection
*/
public function __construct(PDO $connection)
{
$this->connection = $connection;
}
/**
* Get user by the given user id.
*
* @throws DomainException
*
* @return array The user data
*/
public function getUsers(): array
{
$sql = "SELECT user_id, title, firstname, surname, email_address FROM user us;";
$statement = $this->connection->prepare($sql);
$statement->execute();
据我所知,PDO class 本身在 container.php
中实例化 - 我如何修改它以实例化 2 个单独的 PDO classes - 我如何稍后在存储库中使用它们?
为清楚起见,我尝试查看 dependencies.php
,最接近的是 middleware.php
,但是当我尝试这个时,我收到错误 Uncaught Error: Cannot use object of type DI\Container as array in /var/www/config/middleware.php
:
return function (App $app) {
// Parse json, form data and xml
$app->addBodyParsingMiddleware();
// Add global middleware to app
$app->addRoutingMiddleware();
$container = $app->getContainer();
// PDO database library
$container['db'] = function ($c) {
$settings = $c->get('settings')['db'];
$pdo = new PDO("mysql:host=" . $settings['host'] . ";dbname=" . $settings['dbname'],
$settings['user'], $settings['pass']);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
return $pdo;
};
// Error handler
$settings = $container->get(Configuration::class)->getArray('error_handler_middleware');
$display_error_details = (bool)$settings['display_error_details'];
$log_errors = (bool)$settings['log_errors'];
$log_error_details = (bool)$settings['log_error_details'];
$app->addErrorMiddleware($display_error_details, $log_errors, $log_error_details);
};
经过深思熟虑,我想我已经解决了。
我使用容器创建了 PDO 实例
$container = $app->getContainer();
$container->set('db', function(ContainerInterface $c) {
$config = $c->get(Configuration::class);
$host = $config->getString('db.host');
$dbname = $config->getString('db.database');
$username = $config->getString('db.username');
$password = $config->getString('db.password');
$dsn = "mysql:host=$host;dbname=$dbname;";
return new PDO($dsn, $username, $password);
});
$container->set('db_readonly', function(ContainerInterface $c) {
$config = $c->get(Configuration::class);
$host = $config->getString('db_readonly.host');
$dbname = $config->getString('db_readonly.database');
$username = $config->getString('db_readonly.username');
$password = $config->getString('db_readonly.password');
$dsn = "mysql:host=$host;dbname=$dbname;";
return new PDO($dsn, $username, $password);
});
然后更改存储库以在构造函数中使用 App,然后使用容器获取 PDO 实例
/**
* @var PDO The database
*/
private $db;
/**
* @var PDO The readonly database
*/
private $readonly_db;
/**
* Constructor.
*
* @param App $app The database db
*/
public function __construct(App $app)
{
$container = $app->getContainer();
$this->db = $container->get('db');
$this->readonly_db = $container->get('db_readonly');
}
留在这里以防其他人遇到问题,尽管如果有更好的方法,或者可以改进我当前的方法,我将不胜感激反馈