【发布时间】:2018-07-23 20:03:43
【问题描述】:
TL;DR;
如何使 CardOnFile\Controller 类可以使用 PDO 连接,以便它可以进行数据库查询? (我想我必须使用容器,但不确定如何使用)。
背景
每次实例化需要访问数据库的对象时,我都希望避免与数据库建立多个连接。所以,我认为我需要实例化一个数据库连接 (PDO) 的副本,然后使用 League\Route 和 League\Container 将其注入到需要它的类中。
我不想将容器注入到类中,因为那是服务位置。但是,我完全不确定如何将 PDO 对象放入需要它的类中,以便它可以工作。
如何使映射的可调用对象具有数据库访问权限?
代码:
/* Connect to a MySQL database using driver invocation */
$dsn = 'mysql:dbname=foo;host=localhost';
$user = 'bar';
$password = 'supersecret';
try {
$pdo = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
die(__FILE__ . ":" . __LINE__);
}
$container = new League\Container\Container;
$container->share('response', Zend\Diactoros\Response::class);
$container->share('request', function () {
return Zend\Diactoros\ServerRequestFactory::fromGlobals(
$_SERVER, $_GET, $_POST, $_COOKIE, $_FILES
);
});
$container->share('emitter', Zend\Diactoros\Response\SapiEmitter::class);
//DI PDO instance and connection.
$container->share('PDO', $pdo);
$route = new League\Route\RouteCollection($container);
$route->map('GET', '/cards/', 'CardOnFile\Controller::requestEmail' );
$route->map('GET', '/cards/emails/confirm', 'CardOnFile\Controller::getUserController' );
$route->map('GET', '/cards/emails/', 'CardOnFile\Controller::getCardController' );
$response = $route->dispatch($container->get('request'), $container->get('response'));
$container->get('emitter')->emit($response);
【问题讨论】:
-
FWIW:Design Patterns: How to create database object/connection only when needed?。猜猜我的典型方法是单例(带有工厂/注册表?)。我想在 ZF 和 Symfony 中如何使用 Doctrine。
-
这很有用,我同意它,但我不知道如何穿透
$route->map()的范围来提供数据库实例或将$pdo变量传递给类本身。 -
编辑重新措辞问题,使我需要帮助更清楚。
-
在 Controller 中获取连接,我可能只是从静态工厂类中获取默认连接。不确定您的应用程序是否像某些框架一样具有“控制器助手”的概念。
$db = $this->_helper->dbManager()...你在使用框架吗?你有某种数据库/模型方法吗? -
我没有使用框架。您在此处列出的方法是有效的,但我试图远离使用全局命名空间。不确定我是否可以通过这种方式对其进行单元测试。
标签: php dependency-injection routes containers