2016-07-25 45 views
0

我目前正在学习zend表达式,我可以看到有关如何访问路由/动作中的中间件的几个选项。Zend表达式 - 注入中间件的最佳方式

在富有表现力的框架应用程序中,有一个HomePageFactory在其中注入容器,然后从容器中拉出路由器,模板引擎等,并使用它们构造一个新的HomePageAction类并返回。

例如:

class HomePageFactory 
{ 
    public function __invoke(ContainerInterface $container) 
    { 
     $router = $container->get(RouterInterface::class); 
     $template = ($container->has(TemplateRendererInterface::class)) 
      ? $container->get(TemplateRendererInterface::class) 
      : null; 

     return new HomePageAction($router, $template); 
    } 

我然后需要闪光信使和整个下列传来:

class SlimFlashMiddlewareFactory 
{ 
    public function __invoke($container) 
    { 
     return function ($request, $response, $next) { 
      // Start the session whenever we use this! 
      session_start(); 

      return $next(
       $request->withAttribute('flash', new Messages()), 
       $response 
      ); 
     }; 
    } 
} 

因此,这是稍有不同,并且将所述中间件经由一个属性的请求。其中,其需要通过类似然后可以检索:

$flashMessenger = $request->getAttribute('flash'); 

因此,其实我的问题是什么让以FlashMessenger进入行动的这两种方法的优点/缺点是什么?

如果我有一个UserService处理从数据库中检索用户,因此可能需要多个操作/路由,我最好是修改HomePageAction工厂(以及任何需要它的其他人)来接受UserService ?

class HomePageFactory 
    { 
     public function __invoke(ContainerInterface $container) 
     { 
      $router = $container->get(RouterInterface::class); 
      $template = ($container->has(TemplateRendererInterface::class)) 
       ? $container->get(TemplateRendererInterface::class) 
       : null; 
      $userService = $container->get(App\UserService::class); 

      return new HomePageAction($router, $template, $userService); 
     } 

或者,我会更好地与以FlashMessenger如何工作(这似乎有点更易于管理)去,它通过一个属性添加到请求访问需要的地方呀?

$userService = $request->getAttribute('UserService'); 

我不知道是否有与后者选择任何性能问题,但我也明白,它可以以这种方式仅针对特定的路线,而不是UserServer的是应用广泛进行。我的直觉(写出这个问题后)是真的,这是一个服务,而不是真正的中间件,所以我应该真的在修改HomePageAction工厂并添加UserService,而不是做那些看起来更简单和使用属性ala FlashMessenger。但如果上师能够帮助澄清这一点,这将非常方便。

非常感谢提前。

回答

1

我不知道性能差异,因为我没有测试过这个。但我想你需要问自己的问题是这个班是做什么的?在调用Action类之前或之后是否需要其他中间件,或者您是否仅在Action类或应用程序中的其他位置需要它。

在您的情况下,UserService可能会负责注册或更新用户。当你的直觉告诉你时,那些东西会被注入ActionFactory。但是,对于身份验证,如果使用中间件完成,则会有所不同。首先,您需要在您的身份验证中间件中使用该类,您可以使用该请求传递给授权中间件(或者只传递经过身份验证的用户对象,这就是我所做的)。

所以,我猜的经验法则是,如果需要在Action之前/之后更改传入请求或传出响应,请将其传递给Request,否则将其注入Action with a Factory。

如果您开始通过请求传递所有内容,将很难跟踪。我发现尽可能多地注入Action本身会容易得多,因为那样我就可以轻松地看到该类中需要什么,并且我可以更容易地进行测试。

事情就像一个Flash Messenger,会话和认证用户,我会在请求中注入。

+0

感谢您花时间回复。这个特定的UserService不处理认证,因此不需要修改请求。所以我认为我已经在正确的方向上注入了行动。感谢您的理智检查和澄清。 – Neddage