2016-01-17 8 views
14

Я читал, что в Slim v2 приложение $ привязано к классу промежуточного ПО. Я нахожу, что это не так в v3? Ниже мой класс промежуточного слоя, но я просто получать неопределенный:

<?php 
namespace CrSrc\Middleware; 

class Auth 
{ 
    /** 
    * Example middleware invokable class 
    * 
    * @param \Psr\Http\Message\ServerRequestInterface $request PSR7 request 
    * @param \Psr\Http\Message\ResponseInterface  $response PSR7 response 
    * @param callable         $next  Next middleware 
    * 
    * @return \Psr\Http\Message\ResponseInterface 
    */ 
    public function __invoke($request, $response, $next) 
    { 
     // before 

var_dump($this->getContainer()); // method undefined 
var_dump($this->auth); exit; // method undefined 
     if (! $this->get('auth')->isAuthenticated()) { 
      // Not authenticated and must be authenticated to access this resource 
      return $response->withStatus(401); 
     } 

     // pass onto the next callable 
     $response = $next($request, $response); 

     // after 


     return $response; 
    } 
} 

Что такое правильный способ доступа к контейнеру DI внутри промежуточного слоя? Я предполагаю, что должен быть способ?

ответ

21

немного поздно к партии, но могли бы помочь другим ... Вы должны вводить свой контейнер, когда инстанцировании промежуточное

$container = $app->getContainer(); 
$app->add(new Auth($container)); 

И ваш промежуточного слоя нужен конструктор

<?php 
namespace CrSrc\Middleware; 

class Auth 
{ 

    private $container; 

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

    /** 
    * Example middleware invokable class 
    * 
    * @param \Psr\Http\Message\ServerRequestInterface $request PSR7 request 
    * @param \Psr\Http\Message\ResponseInterface  $response PSR7 response 
    * @param callable         $next  Next middleware 
    * 
    * @return \Psr\Http\Message\ResponseInterface 
    */ 
    public function __invoke($request, $response, $next) 
    { 
     // $this->container has the DI 

    } 
} 

LE: Развернув бит начального ответа, контейнер получает injected in the constructor, если вы поставляете промежуточное ПО как класс Строка

$app->add('Auth'); 

или

$app->add('Auth:similarToInvokeMethod') 
+0

Спасибо. Я думаю, что в конце концов я просто предположил, что это был путь к v3. Кажется, все равно работает. – Martyn

+0

Отличный ответ. Многие люди, использующие Slimphp, ищут этот ответ, но скрыты за кустами, известными как Injection Dependency. Благодаря! – user2800382

-1

Насколько я понимаю, код, Слим (v3) работает следующим образом:

  • если вы передаете закрытия, как промежуточного слоя, то он вызывает bindTo с контейнером, как парам.
  • если вы передаете класс/строку, устраняющую к классу, то Сольет создает экземпляр и передает контейнер как пары конструктору

    <?php 
    $app->add(Auth); 
    
  • в противном случае (например, при добавлении промежуточного слоя экземпляра, созданный ранее), то похоже, что вам нужно позаботиться о передаче всех необходимых ссылок.

+0

Это отчасти верно: 'bindTo' применяется Closures при передаче в качестве промежуточного слоя, но если вы передаете класс он не будет ничего поставлять в конструкторе –

+0

@ в- noob Я только что протестировал его с помощью Slim 3.0.0 и добавил промежуточное программное обеспечение, используя созданный экземпляр контейнера '$ app-> add (ClassName)' ClassName' в качестве первого параметра для конструктора. – Rafael

+0

, что происходит, только если вы предоставите вызываемое промежуточное ПО в виде строки. Он перейдет в [CallableResolver :: разрешение] (https://github.com/slimphp/Slim/blob/3.x/Slim/CallableResolver.php#L51-L79), и этот метод будет создавать экземпляр вашего класса. Я предполагаю, что неправильный оператор - 'class/string' ... это действительно просто' string'. –