Php 如何在Slim 4中注入多个PDO实例

Php 如何在Slim 4中注入多个PDO实例,php,pdo,slim,Php,Pdo,Slim,我刚刚开始使用Slim 4(Slim作为一个整体也是全新的),在阅读和阅读了一些文章之后,我成功地获得了一个带有PDO连接到DB的框架应用程序设置 我现在希望注入第二个PDO实例,以便根据请求使用第二个数据库,尽管我正努力弄清楚如何做到这一点 我当前的设置是: settings.php $settings['db'] = [ 'driver' => 'mysql', 'host' => 'database', 'username' => 'root',

我刚刚开始使用Slim 4(Slim作为一个整体也是全新的),在阅读和阅读了一些文章之后,我成功地获得了一个带有PDO连接到DB的框架应用程序设置

我现在希望注入第二个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,
    ],
];
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);
    },

];
container.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,
    ],
];
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类本身是在
container.php
中实例化的-我如何修改它以实例化两个单独的PDO类-以及以后如何在存储库中使用它们

为了清楚起见,我试着看了一下,但我不太明白在哪里定义PDO类。我还查看了一些似乎没有帮助的内容-我没有
依赖项.php
,最接近的是
中间件.php
,但当我尝试这样做时,我得到了错误
未捕获错误:无法在/var/www/config/middleware.php中将DI\Container类型的对象用作数组:

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);
    });
/**
     * @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');
    }
然后将存储库更改为在构造函数中使用应用程序,然后使用容器获取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);
    });
/**
     * @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');
    }
如果其他人有问题,请将此留在这里,尽管如果有更好的方法,或者我目前的方法可以改进,我将非常感谢您的反馈