0

我目前正在学习 zend expressive,我可以看到一些关于如何在路由/操作中访问中间件的选项。

在富有表现力的骨架应用程序中,有一个 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 Messenger 并遇到以下问题:

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?

IE

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 的工作方式(这似乎更容易管理)并通过属性将其添加到请求中,以便在需要的地方以这种方式访问​​它?

IE

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

我想知道后一个选项是否存在任何性能问题,尽管我确实理解它只能以这种方式完成特定路由,而不是 UserServer 是应用程序范围的。

我的直觉(在写出这个问题之后)是真的,这是一个服务而不是真正的中间件,所以我真的应该修改 HomePageAction 和工厂并以这种方式添加 UserService 而不是做看起来更容易的事情并使用属性 ala FlashMessenger . 但是,如果大师可以帮助澄清这一点,那将非常方便。

提前谢谢了。

4

1 回答 1

1

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

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

所以我想经验法则是,如果需要在动作之前/之后更改传入的请求或传出的响应,则将其与请求一起传递,否则将其注入到具有工厂的动作中。

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

我会在请求中注入诸如 flash messenger、会话和经过身份验证的用户之类的东西。

于 2016-07-26T20:50:59.003 回答