Slim php - 从中​​间件访问容器

Slim php - access container from middleware

我正在尝试从我的中间件访问 $container,但运气不佳。

在我的 index.php 文件中我有

require '../../vendor/autoload.php';
include '../bootstrap.php';

use somename\Middleware\Authentication as Authentication;

$app = new \Slim\App();
$container = $app->getContainer();
$app->add(new Authentication());

然后我有一个像这样的classAuthentication.php

namespace somename\Middleware;

class Authentication {
  public function __invoke($request, $response, $next) {
    $this->logger->addInfo('Hi from Authentication middleware');

但是我得到一个错误

Undefined property: somename\Middleware\Authentication::$logger in ***

我也尝试将以下构造函数添加到 class 但我也没有得到任何乐趣。

 private $container;

 public function __construct($container) {
     $this->container = $container;
 }

有人能帮忙吗?

中间件实现的最佳实践是这样的:

将此代码放入您的依赖项部分:

$app = new \Slim\App();
$container = $app->getContainer();
/** Container will be passed to your function automatically **/
$container['MyAuthenticator'] = function($c) {
    return new somename\Middleware\Authentication($c);
};

然后在您的 Authentication class 中像您提到的那样创建构造函数: 命名空间 somename\Middleware;

class Authentication {
    protected $container;

    public function __invoke($request, $response, $next)
    {
        $this->container->logger->addInfo('Hi from Authentication middleware');
    }

    public function __construct($container) {
        $this->container = $container;
    }

    /** Optional : Add __get magic method to easily use container 
        dependencies 
        without using the container name in code 
        so this code : 
        $this->container->logger->addInfo('Hi from Authentication middleware'); 
        will be this :
        $this->logger->addInfo('Hi from Authentication middleware');
    **/

    public function __get($property)
    {
        if ($this->container->{$property}) {
            return $this->container->{$property};
        }
    }
}

在你的 index.php 中使用这样的名称解析添加中间件:

$app->add('MyAuthenticator');

我不同意. When adding this PHP __magic function__get),代码会更难测试。

应在构造函数中指定所有必需的依赖项。 好处是,您可以轻松地看到 class 具有哪些依赖项,因此只需要在单元测试中模拟这些 classes,否则您将不得不在每个测试中创建一个容器。还有Keep It Simple Stupid

我将在记录器示例中展示:

class Authentication {
    private $logger;

    public function __construct($logger) {
        $this->logger = $logger;
    }

    public function __invoke($request, $response, $next) {
        $this->logger->addInfo('Hi from Authentication middleware');
    }
}

然后将带有logger参数的中间件添加到容器中:

$app = new \Slim\App();
$container = $app->getContainer();
$container['MyAuthenticator'] = function($c) {
    return new somename\Middleware\Authentication($c['logger']);
};

注意:上面的容器注册可以使用 PHP-DI Slim 自动完成(但应该也更慢)。