Applications

In zend-expressive, you define a Zend\Expressive\Application instance and execute it. The Application instance is itself middleware that composes:

You can define the Application instance in several ways:

Regardless of how you setup the instance, there are several methods you will likely interact with at some point or another.

Instantiation

As noted at the start of this document, we provide several ways to create an Application instance.

Constructor

If you wish to manually instantiate the Application instance, it has the following constructor:

/**
 * @param Zend\Expressive\Router\RouterInterface $router
 * @param null|Psr\Container\ContainerInterface $container IoC container from which to pull services, if any.
 * @param null|Interop\Http\ServerMiddleware\DelegateInterface $defaultDelegate
 *     Delegate to invoke when the internal middleware pipeline is exhausted
 *     without returning a response.
 * @param null|Zend\Diactoros\Response\EmitterInterface $emitter Emitter to use when `run()` is
 *     invoked.
 */
public function __construct(
    Zend\Expressive\Router\RouterInterface $router,
    Psr\Container\ContainerInterface $container = null,
    Interop\Http\ServerMiddleware\DelegateInterface $defaultDelegate = null,
    Zend\Diactoros\Response\EmitterInterface $emitter = null
);

If no container is provided at instantiation, then all routed and piped middleware must be provided as callables.

AppFactory

Zend\Expressive\AppFactory provides a convenience layer for creating an Application instance; it makes the assumption that you will use defaults in most situations, and likely only change which container and/or router you wish to use. It has the following signature:

AppFactory::create(
    Psr\Container\ContainerInterface $container = null,
    Zend\Expressive\Router\RouterInterface $router = null
);

When no container or router are provided, it defaults to:

Container factory

We also provide a factory that can be consumed by a PSR-11 dependency injection container; see the container factories documentation for details.

Adding routable middleware

We discuss routing vs piping elsewhere; routing is the act of dynamically matching an incoming request against criteria, and it is one of the primary features of zend-expressive.

Regardless of which router implementation you use, you can use the following methods to provide routable middleware:

route()

route() has the following signature:

public function route(
    $pathOrRoute,
    $middleware = null,
    array $methods = null,
    $name = null
) : Zend\Expressive\Router\Route

where:

This method is typically only used if you want a single middleware to handle multiple HTTP request methods.

get(), post(), put(), patch(), delete(), any()

Each of the methods get(), post(), put(), patch(), delete(), and any() proxies to route() and has the signature:

function (
    $pathOrRoute,
    $middleware = null,
    $name = null
) : Zend\Expressive\Router\Route

Essentially, each calls route() and specifies an array consisting solely of the corresponding HTTP method for the $methods argument.

Piping

Because zend-expressive builds on zend-stratigility, and, more specifically, its MiddlewarePipe definition, you can also pipe (queue) middleware to the application. This is useful for adding middleware that should execute on each request, defining error handlers, and/or segregating applications by subpath.

The signature of pipe() is:

public function pipe($pathOrMiddleware, $middleware = null)

where:

Unlike Zend\Stratigility\MiddlewarePipe, Application::pipe() allows fetching middleware by service name. This facility allows lazy-loading of middleware only when it is invoked. Internally, it wraps the call to fetch and dispatch the middleware inside a closure.

Additionally, we define a new method, pipeErrorHandler(), with the following signature:

public function pipeErrorHandler($pathOrMiddleware, $middleware = null)

It acts just like pipe() except when the middleware specified is a service name; in that particular case, when it wraps the middleware in a closure, it uses the error handler signature:

function ($error, ServerRequestInterface $request, ResponseInterface $response, callable $next);

Read the section on piping vs routing for more information.

Registering routing and dispatch middleware

Routing is accomplished via dedicated middleware, Zend\Expressive\Middleware\RouteMiddleware; similarly, dispatching of routed middleware has a corresponding middleware, Zend\Expressive\Middleware\DispatchMiddleware. Each can be piped/registered with other middleware platforms if desired.

These methods MUST be piped to the application so that the application will route and dispatch routed middleware. This is done using the following methods:

$app->pipeRoutingMiddleware();
$app->pipeDispatchMiddleware();

See the section on piping to see how you can register non-routed middleware and create layered middleware applications.

Changed in version 2.2

Starting in version 2.2, the methods pipeRoutingMiddleware and pipeDispatchMiddleware are deprecated in favor of piping the middleware manually.

Additionally, the middleware has been ported to the zend-expressive-router package, under the namespace Zend\Expressive\Router\Middleware. We suggest piping them by service name. Please see our migration documentation for more details, and for information on how to automatically update your application.

Retrieving dependencies

As noted in the intro, the Application class has several dependencies. Some of these may allow further configuration, or may be useful on their own, and have methods for retrieving them. They include:

Deprecated

Each of the above methods are deprecated starting in version 2.2, and will be removed in version 3.0.

Executing the application: run()

When the application is completely setup, you can execute it with the run() method. The method may be called with no arguments, but has the following signature:

public function run(
    ServerRequestInterface $request = null,
    ResponseInterface $response = null
);