zendframework/zend-stratigility
Zend Stratigility is a lightweight middleware pipeline for PHP, built around PSR-7 HTTP messages. Compose request/response processing with reusable middleware, route-like piping, and error handling—ideal for building microservices or adding middleware to existing apps.
Start by installing zendframework/zend-stratigility via Composer (note: package is archived; consider migrating to middlewares/utils or nyholm/psr7-server for newer projects). For initial use, instantiate a Server or MiddlewarePipe, attach middleware callables or classes implementing Interop\Http\ServerMiddleware\MiddlewareInterface, and dispatch with process().
First use case: build a minimal microservice handling JSON API requests. Create a basic pipeline: authentication → routing → controller → final handler for error responses. Use MiddlewarePipe::pipe($path, $middleware) to scope middleware to URL prefixes.
Look first at the MiddlewarePipe class and Server class in the Zend\Stratigility namespace—these form the core pipeline surface. Check src/Http/ServerRequest.php and src/Utils.php for helpers like prepareResponse() and prepareRequest(). The test/ directory contains useful examples (e.g., test/Asset/Middleware/Foo.php).
pipe('/api', $apiMiddleware) for prefix-scoped routes.__invoke(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface. Avoid direct access to globals—inject dependencies via constructor.PathMiddlewareDecorator to wrap middleware so it only executes if the path matches (e.g., for /admin).pipe(null, $finalHandler) or setDispatch($finalHandler) to return consistent error responses (e.g., 500 with JSON).php-http/discovery + guzzlehttp/psr7 or nyholm/psr7 for PSR-7 support. Use MiddlewarePipe::pipe() instead of Next::handle() to avoid tight coupling to Next (deprecated in newer forks).zendframework/zend-stratigility is unmaintained. Prefer middlewares/utils (its spiritual successor) or nyholm/psr7-server + a modern router (e.g., symfony/routing).pipe() matching is prefix-based, not exact. pipe('/api', $m) matches /api, /api/users, /api/123, but not /api with trailing slash unless normalized.$handler->handle($request) unless short-circuiting (e.g., auth rejection).$response = $response->withStatus(401))—otherwise changes won’t propagate.setDispatch() is used or custom error middleware catches it. Use pipe(null, new ErrorMiddleware()) as last resort.ServerRequestInterface and RequestHandlerInterface, asserting on handle() arguments and returned response. Use MiddlewarePipe::process() for integration tests.How can I help you explore Laravel packages today?