Slim Framework 中的依赖注入 - 将 Container 传递给你自己的 类
Dependency Injection in Slim Framework - passing Container into your own classes
我已经评论过这个话题,但它似乎已经死了所以我打开一个新的:
上面的 post 解释了如何将 Slims Container 传递给您自己编写的 class。
但是,OP 询问是否有可能让 Slim 进行依赖注入 ALL 他们的 classes.
我也很想知道是否有办法做到这一点,因为如果你必须将容器传递给 every class 你想使用它。
例如,如果我想使用 Slim 的功能之一(例如进行重定向,在我自己的 classes 之一中)我不能使用根据文档:
$res->withStatus(302)->withHeader('Location', 'your-new-uri');
因为$res
(响应对象)不在我class的范围内,除非我inject/pass它。
这个问题是,如果我说 100 classes,我是否必须通过(或注入)容器 100 次?这看起来真的非常乏味。
在像 CakePHP 这样的框架中,您可以使用 'AppController' 在全局范围内做这样的事情,即定义一次,并使其在您的所有 class 中可用。 Slim 不提供这个功能吗?如果不是,那是一个严重的缺点,IMO。
编辑 - 我从我发表的评论之一中添加此内容以尝试进一步解释该问题:
如果您查看第一个应用程序教程 - http://slimframework.com/docs/tutorial/first-app.html - 他们正在向容器添加 PDO 数据库连接。
假设我在子目录中有 100 个单独的 classes(该示例有一个 ../classes/ 目录)并使用 index.php 自动加载它们 spl_autoload_register()
。该容器在任何 classes 中都不可用。
如果我必须分别传递某些东西 100 次,每次我使用我的 classes 之一,只是为了获得 PDO 连接(这只是一个例子),那么这会使代码非常重复,即不干燥。
Slim 默认自带 Pimple。一些开发人员争论(我倾向于同意他们的观点)Pimple 不是一个依赖注入容器,而是一个服务定位器,因为它不会自己解决依赖关系,你需要注册它们。
Slim 3 可与任何实现 Container interop interface 的依赖管理器一起工作,而 PHP-DI 可以。
争取 this package. This is what I'm using for my projects and it's simply amazing, because of autowiring。简而言之,PHP-DI 读取 class 的构造函数并了解需要注入的内容,儿子,您不必像使用 Pimple 那样注册依赖项。
有时我认为(希望?)PHP-DI 将取代 Pimple 作为 Slim 的默认 DI 容器,因为它更先进。
以下是你如何处理疙瘩:
<?php
namespace Controllers;
class UsersController
{
// Inject Container in controller (which is bad, actually)
public function __construct(ContainerInterface $container)
{
// grab instance from container
$this->repository = $container['userRepository'];
}
// Handler of a route
public function getAllUsers($request, $response)
{
$user = $this->repository->getAllUsers();
return $response->withJson($users);
}
}
这是与 PHP-DI 相同的控制器:
<?php
namespace Controllers;
class UsersController
{
// Declare your dependencies in constructor:
// PHP-DI will find the classes and inject them automatically
public function __construct(UserRepository $repository)
{
$this->repository = $repository;
}
// Handler of a route
public function getAllUsers($request, $response)
{
$user = $this->repository->getAllUsers();
return $response->withJson($users);
}
}
The problem with this is, if I have say 100 classes, do I have to pass
(or inject) the container 100 times? That seems really, really
tedious.
如果您使用与 PHP-DI 捆绑在一起的 Slim,问题会通过自动装配自动 解决。 :)
最简单的方法如下:
index.php
$app->get('/mytest', '\TestController:mytest');
TestController.php
class TestController {
protected $ci;
public function __construct(Slim\Container $ci) {
//var_dump($ci);
$this->ci = $ci;
}
public function mytest() {
$sql = ''; // e.g. SQL query
$stmt = $this->ci->db->prepare($sql);
}
}
我不确定这是否是 "correct" 的实现方式,但是发生的是 TestController
的构造函数接收容器作为第一个参数。这在他们的文档中提到:http://www.slimframework.com/docs/objects/router.html#container-resolution
因此,当您使用像 TestController::mytest()
这样的函数时,它可以访问容器中的任何内容,例如您在 index.php 中设置的 PDO 数据库实例(如果遵循他们的第一个应用程序示例教程)。
正如我所说,我不确定这是否是 "right" 的做法,但它确实有效。
如果取消注释 var_dump($ci)
行,您将看到 Slim Container 对象。
如果有人对此有任何反馈,请发表评论,因为我很想知道。
我已经评论过这个话题,但它似乎已经死了所以我打开一个新的:
上面的 post 解释了如何将 Slims Container 传递给您自己编写的 class。
但是,OP 询问是否有可能让 Slim 进行依赖注入 ALL 他们的 classes.
我也很想知道是否有办法做到这一点,因为如果你必须将容器传递给 every class 你想使用它。
例如,如果我想使用 Slim 的功能之一(例如进行重定向,在我自己的 classes 之一中)我不能使用根据文档:
$res->withStatus(302)->withHeader('Location', 'your-new-uri');
因为$res
(响应对象)不在我class的范围内,除非我inject/pass它。
这个问题是,如果我说 100 classes,我是否必须通过(或注入)容器 100 次?这看起来真的非常乏味。
在像 CakePHP 这样的框架中,您可以使用 'AppController' 在全局范围内做这样的事情,即定义一次,并使其在您的所有 class 中可用。 Slim 不提供这个功能吗?如果不是,那是一个严重的缺点,IMO。
编辑 - 我从我发表的评论之一中添加此内容以尝试进一步解释该问题:
如果您查看第一个应用程序教程 - http://slimframework.com/docs/tutorial/first-app.html - 他们正在向容器添加 PDO 数据库连接。
假设我在子目录中有 100 个单独的 classes(该示例有一个 ../classes/ 目录)并使用 index.php 自动加载它们 spl_autoload_register()
。该容器在任何 classes 中都不可用。
如果我必须分别传递某些东西 100 次,每次我使用我的 classes 之一,只是为了获得 PDO 连接(这只是一个例子),那么这会使代码非常重复,即不干燥。
Slim 默认自带 Pimple。一些开发人员争论(我倾向于同意他们的观点)Pimple 不是一个依赖注入容器,而是一个服务定位器,因为它不会自己解决依赖关系,你需要注册它们。
Slim 3 可与任何实现 Container interop interface 的依赖管理器一起工作,而 PHP-DI 可以。
争取 this package. This is what I'm using for my projects and it's simply amazing, because of autowiring。简而言之,PHP-DI 读取 class 的构造函数并了解需要注入的内容,儿子,您不必像使用 Pimple 那样注册依赖项。
有时我认为(希望?)PHP-DI 将取代 Pimple 作为 Slim 的默认 DI 容器,因为它更先进。
以下是你如何处理疙瘩:
<?php
namespace Controllers;
class UsersController
{
// Inject Container in controller (which is bad, actually)
public function __construct(ContainerInterface $container)
{
// grab instance from container
$this->repository = $container['userRepository'];
}
// Handler of a route
public function getAllUsers($request, $response)
{
$user = $this->repository->getAllUsers();
return $response->withJson($users);
}
}
这是与 PHP-DI 相同的控制器:
<?php
namespace Controllers;
class UsersController
{
// Declare your dependencies in constructor:
// PHP-DI will find the classes and inject them automatically
public function __construct(UserRepository $repository)
{
$this->repository = $repository;
}
// Handler of a route
public function getAllUsers($request, $response)
{
$user = $this->repository->getAllUsers();
return $response->withJson($users);
}
}
The problem with this is, if I have say 100 classes, do I have to pass (or inject) the container 100 times? That seems really, really tedious.
如果您使用与 PHP-DI 捆绑在一起的 Slim,问题会通过自动装配自动 解决。 :)
最简单的方法如下:
index.php
$app->get('/mytest', '\TestController:mytest');
TestController.php
class TestController {
protected $ci;
public function __construct(Slim\Container $ci) {
//var_dump($ci);
$this->ci = $ci;
}
public function mytest() {
$sql = ''; // e.g. SQL query
$stmt = $this->ci->db->prepare($sql);
}
}
我不确定这是否是 "correct" 的实现方式,但是发生的是 TestController
的构造函数接收容器作为第一个参数。这在他们的文档中提到:http://www.slimframework.com/docs/objects/router.html#container-resolution
因此,当您使用像 TestController::mytest()
这样的函数时,它可以访问容器中的任何内容,例如您在 index.php 中设置的 PDO 数据库实例(如果遵循他们的第一个应用程序示例教程)。
正如我所说,我不确定这是否是 "right" 的做法,但它确实有效。
如果取消注释 var_dump($ci)
行,您将看到 Slim Container 对象。
如果有人对此有任何反馈,请发表评论,因为我很想知道。