Zend Expressive嵌套应用程序

时间:2017-09-20 15:28:41

标签: zend-expressive

我试图使用zend富有表现力的嵌套应用程序,所以我关注这篇博文: 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

有什么我从这篇博文中找不到的东西吗?

2 个答案:

答案 0 :(得分:2)

您将工厂命名为CreateBookMiddlewareFactory。然后在__invoke$nested->pipe(CreateBookMiddleware::class);。这取决于您的配置,但通常CreateBookMiddlewareFactory将是CreateBookMiddleware的工厂。所以它停留在一个循环中,因为它不断创造自己。

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

我已经通知了博文的作者。

编辑:使用此修补程序更新博客文章:

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;
    }
}

答案 1 :(得分:0)

我接受@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;
    }
}