Zend Expressive - 注入中间件的最佳方式

时间:2016-07-25 21:44:29

标签: php middleware zend-expressive

我目前正在学习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);
    }

然后我需要一个flash信使并且遇到了以下内容:

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 个答案:

答案 0 :(得分:1)

由于我还没有对此进行测试,因此我不了解性能差异。但我想你需要问自己的问题是这堂课做了什么?在调用Action类之前或之后是否需要其他中间件,或者仅在Action类或应用程序中的其他位置需要它。

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

所以我猜测经验法则是,如果在Action之前/之后需要更改传入的Request或传出的Response,则使用Request传递它,否则将其注入Action with a Factory。

如果您开始使用请求传递所有内容,则很难跟踪。我发现尽可能多地注入Action本身要容易得多,因为我可以很容易地看到该类中需要什么,我可以更容易地测试它。

像闪回信使,会话和我将在请求中注入的经过身份验证的用户。