zendframework / zend-stratigility

Middleware for PHP built on top of PSR-7 and PSR-15
BSD 3-Clause "New" or "Revised" License
235 stars 57 forks source link

Example in documentation throws a fatal error #100

Closed patrick-fls closed 7 years ago

patrick-fls commented 7 years ago

Using 2.0.1 https://zendframework.github.io/zend-stratigility/middleware/

Will throw

Fatal error: Uncaught Zend\Stratigility\Exception\MissingResponsePrototypeException:
Cannot wrap callable middleware; no Zend\Stratigility\Middleware\CallableMiddlewareWrapperFactory
or Psr\Http\Message\ResponseInterface instances composed in middleware pipeline; use
setCallableMiddlewareDecorator() or setResponsePrototype() on your Zend\Stratigility\MiddlewarePipe
instance to provide one or the other, or decorate callable middleware manually before piping.
weierophinney commented 7 years ago

Which example, specifically?

Also, the exception details what you need to do; what we'll be doing is updating the example to add the response prototype, but first we need to know which example is leading to the error you're seeing.

patrick-fls commented 7 years ago

this one:

use Zend\Stratigility\MiddlewarePipe;
use Zend\Diactoros\Server;

require __DIR__ . '/../vendor/autoload.php';

$app    = new MiddlewarePipe();
$server = Server::createServer($app, $_SERVER, $_GET, $_POST, $_COOKIE, $_FILES);

// Landing page
$app->pipe('/', function ($req, $res, $next) {
    if (! in_array($req->getUri()->getPath(), ['/', ''], true)) {
        return $next($req, $res);
    }
    $res->getBody()->write('Hello world!');
    return $res;
});

// Another page
$app->pipe('/foo', function ($req, $res, $next) {
    $res->getBody()->write('FOO!');
    return $res;
});

$server->listen();
geerteltink commented 7 years ago

How about this:

<?php

use Zend\Stratigility\MiddlewarePipe;
use Zend\Stratigility\NoopFinalHandler;
use Zend\Diactoros\Server;

require __DIR__ . '/vendor/autoload.php';

$app    = new MiddlewarePipe();
$app->setResponsePrototype(new \Zend\Diactoros\Response());

$server = Server::createServer($app, $_SERVER, $_GET, $_POST, $_COOKIE, $_FILES);

// Landing page
$app->pipe('/', function ($req, $res, $next) {
    if (! in_array($req->getUri()->getPath(), ['/', ''], true)) {
        return $next($req, $res);
    }
    $res->getBody()->write('Hello world!');
    return $res;
});

// Another page
$app->pipe('/foo', function ($req, $res, $next) {
    $res->getBody()->write('FOO!');
    return $res;
});

$server->listen(new NoopFinalHandler());

Original example code is here: https://github.com/zendframework/zend-stratigility/blob/master/doc/book/middleware.md

patrick-fls commented 7 years ago

Yep that works!

weierophinney commented 7 years ago

Fixed with 2c18525. Thanks for the report!

geerteltink commented 7 years ago

@weierophinney That fixed the first part. You still need to supply a final handler to the listener as in my example: $server->listen(new NoopFinalHandler());. Without it you will get this error:

Uncaught TypeError: Argument 2 passed to Zend\Stratigility\MiddlewarePipe::process() must be an instance of Interop\Http\ServerMiddleware\DelegateInterface, null given ...
weierophinney commented 7 years ago

Thanks, @xtreamwayz — updated now with that.