我试图使用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
有什么我从这篇博文中找不到的东西吗?
答案 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;
}
}