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

时间:2018-01-05 18:34:21

标签: php slim

我正在尝试从我的中间件访问$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());

然后我有一个类Authentication.php这样的

namespace somename\Middleware;

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

但我收到错误

  

未定义的属性:somename \ Middleware \ Authentication :: $ logger in ***

我也试过在课堂上添加以下构造函数,但我也没有兴趣。

 private $container;

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

有人可以帮忙吗?

2 个答案:

答案 0 :(得分:2)

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

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

$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类中创建你提到的构造函数:     命名空间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');

答案 1 :(得分:0)

我不同意Ali Kaviani's Answer。添加此PHP __magic function__get)时,代码将更难以测试。

应在构造函数上指定所有必需的依赖项。 好处是,您可以轻松查看类具有哪些依赖关系,因此只需要在单元测试中模拟这些类,否则您将在每个测试中创建容器。另外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自动完成(但也应该更慢)。