Вложенное приложение Zend Expressive

Я пытаюсь использовать вложенное приложение Zend Expressive, поэтому я следую этому сообщению в блоге: 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

Есть ли что-то, что я не понимаю из этого сообщения в блоге?


person benomite    schedule 20.09.2017    source источник


Ответы (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;
    }
}
person xtreamwayz    schedule 21.09.2017

Я принял ответ @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;
    }
}
person benomite    schedule 21.09.2017
comment
Именно так это исправлено в посте только что: веб/коммит/ - person xtreamwayz; 21.09.2017