我正在使用Slim Framework 3.我想将dependencies.php中定义的$logger注入到Router Controller类中.以下是我的工作,有更好的方法吗?
routes.php文件
$app->get('/test', function($request, $response, $args){
$controller = new AccountController($this->get('logger'));
return $controller->test($request, $response, $args);
});
的AccountController
class AccountController{
private $logger;
function __construct($logger){
$this->logger = $logger;
}
public function test($request, $response, $args){
$this->logger->info('i am inside controller');
return $response->withHeader('Content-Type', 'application/json')->write('test');
}
}
在Slim Framework 3文档中,使用路径控制器的正确方法应该是:
$app->get('/test', 'AccountController:test');
但是当我选择以更“优雅”的方式编写路径控制器代码时,如何将$logger注入AccountController?
解决方法:
根据container resolution docs,您应该能够通过控制器内的容器访问您的记录器:
的AccountController
class AccountController
{
protected $ci;
//Constructor
public function __construct(ContainerInterface $ci)
{
$this->ci = $ci;
}
public function test($request, $response, $args)
{
$this->ci->get('logger')->info('i am inside controller');
return $response->withHeader('Content-Type', 'application/json')->write('test');
}
}
当你调用$app-> get(‘/ test’,’AccountController:test’);时,Slim会自动将容器传递给AccountController的构造函数.
话虽这么说,这是一个方便的功能,而不是一个伟大的设计的例子.正如Rob Allen在他的回答中所解释的那样,通过将控制器注入应用程序容器,而不是将容器注入每个控制器,您可以实现更好的模块化,从而更容易测试代码(如果您使用单元测试).
看看他的example Slim application.如果你看一下,例如AuthorController
,你可以看到这个设计控制器类如何不再依赖于提供所有服务的神奇容器.相反,您明确说明构造函数中每个控制器将需要哪些服务.这意味着您可以更轻松地模拟测试场景中的各个依赖项.