Edi*_*son 4 php dependency-injection slim slim-3
我正在使用 Slim Framework 3。我想将$logger定义的dependencies.php注入到路由器控制器类中。下面是我所做的,有没有更好的方法?
路由文件
$app->get('/test', function($request, $response, $args){
$controller = new AccountController($this->get('logger'));
return $controller->test($request, $response, $args);
});
Run Code Online (Sandbox Code Playgroud)
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');
}
}
Run Code Online (Sandbox Code Playgroud)
在 Slim Framework 3 文档中,使用路由控制器的正确方法应该是:
$app->get('/test', 'AccountController:test');
Run Code Online (Sandbox Code Playgroud)
但是,$logger当我选择以这种更“优雅”的方式编写我的路由控制器时,我该如何注入AccountController 呢?
为了使您的控制器更易于测试,您应该通过构造函数将记录器注入控制器。
AccountController 看起来像这样:
class AccountController
{
protected $logger;
public function __construct($logger) {
$this->logger = $logger;
}
public function test($request, $response, $args){
$this->logger->info('i am inside controller');
return $response->withJson(['foo' => 'bar']);
}
}
Run Code Online (Sandbox Code Playgroud)
在 index.php 中设置是这样的:
$container = $app->getContainer();
$container[Logger::class] = function ($c) {
$logger = new \Monolog\Logger('logger');
return $logger;
};
$container[AccountController::class] = function ($c) {
$logger = $c->get(Logger::class);
return new AccountController($logger);
};
$app->get('/test', 'AccountController:test');
Run Code Online (Sandbox Code Playgroud)
请注意,如果您将格式路由 callable 设置为字符串'class name' colon 'method name',那么 Slim 3 会在从 DI 容器中提取控制器类后为您调用该方法。如果类名不是容器的注册键,那么它将实例化它并将容器传递给构造函数。