0

我正在尝试使用 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

这篇博文中有什么我没有得到正确的东西吗?

4

2 回答 2

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;
    }
}
于 2017-09-21T06:34:43.440 回答
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;
    }
}
于 2017-09-21T07:31:19.810 回答