Zend Expressive 嵌套应用程序

Zend Expressive nested application

我正在尝试使用 zend 富有表现力的嵌套应用程序,所以我正在关注此博客 post: https://framework.zend.com/blog/2017-03-15-nested-middleware-in-expressive.html

问题好像出在中间件工厂:

class CreateBookMiddlewareFactory
{
    public function __invoke(ContainerInterface $container)
    {
        $nested = new Application(
          $container->get(RouterInterface::class),
          $container
        );

        $nested->pipe(AuthenticationMiddleware::class);
        $nested->pipe(ContentValidationMiddleware::class);
        $nested->pipe(BodyParamsMiddleware::class);
        $nested->pipe(BookValidationMiddleware::class);
        $nested->pipe(CreateBookMiddleware::class);

        return $nested;
    }
}

我不知道如何将 CreateBookMiddleware 添加到这里的管道中,因为我们在它的工厂中。所以管道将调用工厂,创建一个新的嵌套应用程序,它将调用工厂,这将创建另一个嵌套应用程序...

( ! ) Fatal error: Maximum function nesting level of '256' reached, aborting! in /var/www/project/vendor/zendframework/zend-stratigility/src/Next.php on line
   158

我从这个博客中有没有什么不对的地方 post?

您将工厂命名为 CreateBookMiddlewareFactory。然后在 __invoke 里面你有 $nested->pipe(CreateBookMiddleware::class);。这取决于您的配置,但通常 CreateBookMiddlewareFactory 是 CreateBookMiddleware 的工厂。所以它陷入了一个循环,因为它一直在创建自己。

由于您的代码与博客中的代码完全相同post,我猜这是该博客中的一个错误post。我认为它应该像上一个委托工厂示例中那样:没有最后一个 $nested->pipe(CreateBookMiddleware::class);.

我已经通知博客作者post。

编辑:博客 post 更新了此修复程序:

namespace Acme\Api;

use Acme\AuthenticationMiddleware;
use Acme\ContentNegotiationMiddleware;
use Psr\Container\ContainerInterface;
use Zend\Expressive\Application;
use Zend\Expressive\Helper\BodyParams\BodyParamsMiddleware;
use Zend\Expressive\Router\RouterInterface;

class CreateBookMiddlewareFactory
{
    public function __invoke(ContainerInterface $container)
    {
        $nested = new Application(
          $container->get(RouterInterface::class),
          $container
        );

        $nested->pipe(AuthenticationMiddleware::class);
        $nested->pipe(ContentValidationMiddleware::class);
        $nested->pipe(BodyParamsMiddleware::class);
        $nested->pipe(BookValidationMiddleware::class);

        // If dependencies are needed, pull them from the container and pass
        // them to the constructor:
        $nested->pipe(new CreateBookMiddleware());

        return $nested;
    }
}

我接受了@xtreamwayz 的回答以进行澄清。但我是这样实现的:

class CreateBookMiddlewareFactory
{
    public function __invoke(ContainerInterface $container)
    {
        $nested = new Application(
          $container->get(RouterInterface::class),
          $container
        );

        $nested->pipe($container->get(AuthenticationMiddleware::class));
        $nested->pipe($container->get(ContentValidationMiddleware::class));
        $nested->pipe($container->get(BodyParamsMiddleware::class));
        $nested->pipe($container->get(BookValidationMiddleware::class));
        // instanciate the new class, so it will not call the factory again
        $nested->pipe(new CreateBookMiddleware());

        return $nested;
    }
}