Reference
In This Article
Migrating from version 2 to version 3
In this document, we outline the backwards breaking changes with version 3.0, and provide guidance on how to upgrade your application to be compatible.
- PHP support
- PSR-15
- Pipeline (
MiddlewarePipe
) - Changes in public interfaces
- Signature changes
- Class additions
- Removed classes and exceptions
- Removed methods
- Function additions
PHP support
We now support only PHP versions 7.1 and above. PHP 5.6 and 7.0 support has been dropped.
PSR-15
Stratigility now supports only PSR-15
interfaces. Support of http-interop/http-middleware
has been dropped.
All middleware and request handlers must now implement PSR-15 interfaces, including those Stratigility implements.
As a result, a number of signatures have been changed. Primarily, these were a
matter of updating typehints on
Interop\Http\ServerMiddleware\DelegateInterface
(defined in
http-interop/http-middleware
0.4 and up, an early draft of PSR-15) and
Interop\Http\Server\RequestHandlerInterface
(defined in
http-interop/http-server-handler,
the immediate predecessor to the final spec) to
Psr\Http\Server\RequestHandlerInterface
, and adding the return type hint
Psr\Http\Message\ResponseInterface
.
Signatures affected include:
Zend\Stratigility\MiddlewarePipe::process()
Zend\Stratigility\Middleware\ErrorHandler::process()
Zend\Stratigility\Middleware\NotFoundHandler::process()
Zend\Stratigility\Middleware\OriginalMessages::process()
Zend\Stratigility\MiddlewarePipe::process()
All of these classes now implement the PSR-15 MiddlewareInterface
.
Pipeline - MiddlewarePipe
We now only allow piping Psr\Http\Server\MiddlewareInterface
instances
into the MiddlewarePipe
class.
In version 2, we had a number of internal utilities for identifying other types
of middleware (callable, double-pass, etc.), and would decorate those within the
pipe()
method. This is no longer allowed.
If you wish to use those types, you will need to decorate them using the appropriate decorators as outlined in the Class additions section.
Additionally, MiddlewarePipe
is now marked final
, and may not be directly
extended. Decorate an instance if you wish to provide alternate behavior, or
create your own MiddlewareInterface
implementation to provide alternate
internal logic.
Changes in public interfaces
Signature changes
-
Next::__construct()
: the second parameter now typehints against the PSR-15RequestHandlerInterface
. -
Next::handle()
: the method now provides a return typehint ofPsr\Http\Message\ResponseInterface
. -
MiddlewarePipe
class is marked now asfinal
and implements the new interfaceMiddlewarePipeInterface.
-
MiddlewarePipe::pipe()
: reduces the number of arguments to one, which now typehints againstPsr\Http\Server\MiddlewareInterface
. This means the method can no longer be used to segregate middleware by path. If you want to do that, please useZend\Stratigility\Middleware\PathMiddlewareDecorator
to decorate your middleware and to provide the path prefix it will run under. See the next section for details. -
MiddlewarePipe::process()
: the second parameter now typehints againstPsr\Http\Server\RequestHandlerInterface
, and provides a return typehint ofPsr\Http\Message\ResponseInterface
. -
ErrorHandler::__construct()
andNotFoundHandler::__construct()
: the first parameter of each constructor now expects a PHPcallable
capable of returning a PSR-7ResponseInterface
instance (instead of typehinting directly againstResponseInterface
). This paves the way for usage with the upcoming PSR-17 (HTTP Message Factories) specification, and simplifies re-use of a dependency injection container service (as otherwise you would need to specify a discrete service per class that expects a response prototype, due to mutability of the response body).
Class additions
-
Zend\Stratigility\MiddlewarePipeInterface
extendsPsr\Http\Server\MiddlewareInterface
andPsr\Http\Server\RequestHandlerInterface
, and defines the methodpipe(Psr\Http\Server\MiddlewareInterface $middleware) : void
. It is implemented byMiddlewarePipe
. -
Zend\Stratigility\Middleware\HostMiddlewareDecorator
allows you to segregate middleware by a static host name. This allows executing middleware only if a particular host matches.
// Segregate to hosts matching 'example.com':
$pipeline->pipe(new HostMiddlewareDecorator('example.com', $middleware));
Alternately, use the host()
utility function to generate the instance; see
below.
Zend\Stratigility\Middleware\PathMiddlewareDecorator
allows you to segregate middleware by a static URI path prefix. This allows executing middleware only if a particular path matches, or segregating a sub-application by path.
// Segregate to paths matching '/foo' as the prefix:
$pipeline->pipe(new PathMiddlewareDecorator('/foo', $middleware));
Alternately, use the path()
utility function to generate the instance; see
below.
Zend\Stratigility\Middleware\CallableMiddlewareDecorator
provides the functionality that was formerly provided byZend\Stratigility\Middleware\CallableInteropMiddlewareWrapper
: it provides the ability to decorate PHP callables that have the same or compatible signatures to the PSR-15MiddlewareInterface
. This allows for one-off piping of middleware:
$pipeline->pipe(new CallableMiddlewareDecorator(function ($req, $handler) {
// do some work
$response = $next($req, $handler);
// do some work
return $response;
});
The arguments and return value can be type-hinted, but do not need to be. The decorator provides some checking on the return value in order to raise an exception if a response is not returned.
Alternately, use the middleware()
utility function to generate the instance;
see below.
Zend\Stratigility\Middleware\DoublePassMiddlewareDecorator
provides the functionality that was formerly provided byZend\Stratigility\Middleware\CallableMiddlewareWrapper
. The class now makes the response prototype argument to the constructor optional, and falls back to a zend-diactoros response instance if that library is installed. Internally, it decorates the$handler
as a callable.
$pipeline->pipe(new DoublePassMiddlewareDecorator(function ($req, $res, $next) {
// do some work
$response = $next($req, $res);
// do some work
return $response;
});
Per recommendations in previous versions, if you are using double-pass
middleware, do not operate on the response passed to the middleware; instead,
only operate on the response returned by $next
, or produce a concrete
response yourself.
Alternately, use the doublePassMiddleware()
utility function to create the
instance; see below.
Zend\Stratigility\Exception\ExceptionInterface
- marker for package-specific exceptions.
Removed classes and exceptions
The following classes have been removed:
Zend\Stratigility\Delegate\CallableDelegateDecorator
Zend\Stratigility\Middleware\CallableInteropMiddlewareWrapper
Zend\Stratigility\Middleware\CallableMiddlewareWrapper
Zend\Stratigility\Middleware\CallableMiddlewareWrapperFactory
Zend\Stratigility\MiddlewareInterface
(Please use the PSR-15MiddlewareInterface
instead.)Zend\Stratigility\NoopFinalHandler
Zend\Stratigility\Route
. This was an internal class used byMiddlewarePipe
andNext
, and its removal should not affect consumers.
The following exceptions have been removed:
Zend\Stratigility\Exception\InvalidMiddlewareException
(this is no longer thrown byMiddlewarePipe
, and thus no longer necessary).Zend\Stratigility\Exception\InvalidRequestTypeException
Removed methods
-
MiddlewarePipe::__invoke()
: the class is no longer invokable. Use the methodprocess
instead. -
MiddlewarePipe::setCallableMiddlewareDecorator()
: since we now accept only PSR-15 middleware implementations withinMiddlewarePipe
, this method is no longer needed. Other middleware types should be decorated in aMiddlewareInterface
implementation prior to piping. -
MiddlewarePipe::setResponsePrototype()
: this method is no longer needed, due to removing support for non-MiddlewareInterface
types. -
MiddlewarePipe::hasResponsePrototype()
: this method is no longer needed, due to removing support for non-MiddlewareInterface
types. -
MiddlewarePipe::raiseThrowables()
: this method has been deprecated since 2.0.0, and slated for removal with this version. -
Middleware\ErrorHandler::__invoke()
: this class is no longer invokable. Use theprocess
method instead. -
Middleware\NotFoundHandler::__invoke()
: this class is no longer invokable. Use theprocess
method instead. -
Next::__invoke()
: this class is no longer invokable. Use the methodhandle
instead. -
Next::next()
: this method was a proxy to thehandle()
method, and no longer of use, particularly as the class is an internal detail. -
Next::process()
: this method was a proxy to thehandle()
method, and no longer of use, particularly as the class is an internal detail. -
Next::raiseThrowables()
: this method has been deprecated since 2.0.0, and slated for removal with this version.
Function additions
Release 3.0 adds the following utility functions:
host
function Zend\Stratigility\host(
string $host,
Psr\Http\Server\MiddlewareInterface $middleware
) : Zend\Stratigility\Middleware\HostMiddlewareDecorator
This is a convenience wrapper around instantiation of a
Zend\Stratigility\Middleware\HostMiddlewareDecorator
instance:
$pipeline->pipe(host('example.com', $middleware));
path
function Zend\Stratigility\path(
string $pathPrefix,
Psr\Http\Server\MiddlewareInterface $middleware
) : Zend\Stratigility\Middleware\PathMiddlewareDecorator
This is a convenience wrapper around instantiation of a
Zend\Stratigility\Middleware\PathMiddlewareDecorator
instance:
$pipeline->pipe(path('/foo', $middleware));
middleware
function Zend\Stratigility\middleware(
callable $middleware
) : Zend\Stratigility\Middleware\CallableMiddlewareDecorator
middleware()
provides a convenient way to decorate callable middleware that
implements the PSR-15 middleware signature when piping it to your application.
$pipeline->pipe(middleware(function ($request, $handler) {
// ...
});
doublePassMiddleware
function Zend\Stratigility\doublePassMiddleware(
callable $middleware,
Psr\Http\Message\ResponseInterface $responsePrototype = null
) : Zend\Stratigility\Middleware\DoublePassMiddlewareDecorator
doublePassMiddleware()
provides a convenient way to decorate middleware that
implements the double pass middleware signature when piping it to your application.
$pipeline->pipe(doublePassMiddleware(function ($request, $response, $next) {
// ...
});
If you are not using zend-diactoros as a PSR-7 implementation, you will need to pass a response prototype as well:
$pipeline->pipe(doublePassMiddleware(function ($request, $response, $next) {
// ...
}, $response);
Found a mistake or want to contribute to the documentation? Edit this page on GitHub!