Calls $this->performRouting($request) and passes the enriched request to $handler->handle($request).
performRouting
ServerRequestInterface $request
ServerRequestInterface
Sets RouteContext::ROUTE_PARSER and RouteContext::ROUTING_RESULTS attributes. On RoutingResults::FOUND, prepares the matched route with route arguments and attaches RouteContext::ROUTE. Throws HttpNotFoundException on NOT_FOUND, HttpMethodNotAllowedException (with allowed methods) on METHOD_NOT_ALLOWED, or RuntimeException otherwise.
use Slim\Factory\AppFactory;$app = AppFactory::create();// Register RoutingMiddleware via the App helper before ErrorMiddleware:$app->addRoutingMiddleware();// Any middleware added BEFORE addRoutingMiddleware() (i.e. inner to it) can read RouteContext:$app->addErrorMiddleware(true, true, true);
ErrorMiddleware wraps downstream request execution in a try / catch (Throwable $e) block and delegates caught exceptions or PHP errors to a mapped ErrorHandlerInterface or custom error handler callable. When catching an HttpException, it extracts the most recent ServerRequestInterface via $exception->getRequest() so routing attributes added inside the pipeline remain available to error renderers.
Replaces $request with $exception->getRequest() if $exception instanceof HttpException, resolves the handler via getErrorHandler(get_class($exception)), and invokes it with ($request, $exception, $displayErrorDetails, $logErrors, $logErrorDetails).
getErrorHandler
string $type
callable|ErrorHandler
Checks $this->handlers[$type], then $this->subClassHandlers[$type], then iterates $this->subClassHandlers with is_subclass_of($type, $class), and finally falls back to getDefaultErrorHandler().
getDefaultErrorHandler
(none)
ErrorHandler|callable
Lazily creates a Slim\Handlers\ErrorHandler if $defaultErrorHandler === null, then resolves and returns it via $callableResolver->resolve().
setDefaultErrorHandler
string|callable|ErrorHandlerInterface $handler
self
Sets the default fallback error handler and returns $this.
use DomainException;use Slim\Exception\HttpNotFoundException;use Slim\Factory\AppFactory;$app = AppFactory::create();$errorMiddleware = $app->addErrorMiddleware(false, true, true, $logger);// Register a custom handler for DomainException and all its subclasses$errorMiddleware->setErrorHandler( DomainException::class, CustomDomainErrorHandler::class, true);// Customize the default ErrorHandler (e.g. force JSON output)$defaultHandler = $errorMiddleware->getDefaultErrorHandler();$defaultHandler->forceContentType('application/json');
BodyParsingMiddleware inspects the inbound request's Content-Type header when $request->getParsedBody() is empty, parses the raw request body stream using a media-type parser registry, and returns a new request instance via $request->withParsedBody($parsedBody). Out of the box, it registers parsers for application/json, application/x-www-form-urlencoded, application/xml, and text/xml, and automatically resolves RFC 6839 structured syntax suffixes (+json, +xml).
ErrorMiddleware Handler Resolution Order (Left) and BodyParsingMiddleware Media-Type Dispatch (Right)Source Code
fromdrawlib.canvasimportsave,setupfromdrawlib.linesimportlinefromdrawlib.shapesimportrectanglefromdrawlib.stylesimportStylesfromdrawlib.textimporttextsetup(width=180,height=84)# Left Panel: ErrorMiddlewarerectangle((46,42),width=80,height=74,style=Styles.Neutral.patch(shape_r=3.0),)text((46,73.5),"ErrorMiddleware::getErrorHandler()",style=Styles.PrimaryBold.patch(text_size=11.5))rectangle((46,59),width=66,height=12,style=Styles.PrimaryFlat.patch(shape_r=2.0),)text((46,61.5),"1. Exact Class Match",style=Styles.WhiteBold.patch(text_size=11.0))text((46,56.5),"handlers[type] direct lookup",style=Styles.White.patch(text_size=10.0))rectangle((46,40),width=66,height=12,style=Styles.PrimaryNeutral.patch(shape_r=2.0),)text((46,42.5),"2. Subclass Match",style=Styles.BlackBold.patch(text_size=11.0))text((46,37.5),"is_subclass_of(type, class)",style=Styles.Dark.patch(text_size=10.0))rectangle((46,21),width=66,height=12,style=Styles.SecondaryNeutral.patch(shape_r=2.0),)text((46,23.5),"3. Default ErrorHandler",style=Styles.BlackBold.patch(text_size=11.0))text((46,18.5),"getDefaultErrorHandler()",style=Styles.Dark.patch(text_size=10.0))line((46,53),(46,46),arrow_head="->",style=Styles.PrimaryBold)line((46,34),(46,27),arrow_head="->",style=Styles.PrimaryBold)# Right Panel: BodyParsingMiddlewarerectangle((134,42),width=80,height=74,style=Styles.PrimaryNeutral.patch(shape_r=3.0),)text((134,73.5),"BodyParsingMiddleware::parseBody()",style=Styles.PrimaryBold.patch(text_size=11.5))rectangle((134,59),width=66,height=12,style=Styles.AccentFlat.patch(shape_r=2.0),)text((134,61.5),"1. Exact Media Type",style=Styles.WhiteBold.patch(text_size=11.0))text((134,56.5),"json / form-urlencoded / xml",style=Styles.White.patch(text_size=10.0))rectangle((134,40),width=66,height=12,style=Styles.SecondaryNeutral.patch(shape_r=2.0),)text((134,42.5),"2. RFC 6839 +Suffix Fallback",style=Styles.BlackBold.patch(text_size=11.0))text((134,37.5),"vnd.api+json -> application/json",style=Styles.Dark.patch(text_size=9.5))rectangle((134,21),width=66,height=12,style=Styles.Neutral.patch(shape_r=2.0),)text((134,23.5),"3. Validate & Attach",style=Styles.BlackBold.patch(text_size=11.0))text((134,18.5),"array | object | null -> Request",style=Styles.Dark.patch(text_size=10.0))line((134,53),(134,46),arrow_head="->",style=Styles.PrimaryBold)line((134,34),(134,27),arrow_head="->",style=Styles.PrimaryBold)save()
If $request->getParsedBody() is empty(), parses the body via parseBody($request) and attaches it via $request->withParsedBody($parsedBody) before calling $handler->handle($request).
registerBodyParser
string $mediaType, callable $callable
self
Registers or overrides a parser callable for $mediaType and returns $this.
hasBodyParser
string $mediaType
bool
Returns true if a parser is registered for $mediaType.
getBodyParser
string $mediaType
callable
Returns the registered parser callable for $mediaType. Throws RuntimeException if none exists.
registerDefaultBodyParsers(protected)
(none)
void
Registers the built-in JSON, form-urlencoded, application/xml, and text/xml parsers.
parseBody(protected)
ServerRequestInterface $request
null|array<mixed>|object
Extracts the media type, checks exact match or 'application/' . $suffix fallback, invokes the parser with (string) $request->getBody(), and validates that the return value is array, object, or null (throwing RuntimeException otherwise).
getMediaType(protected)
ServerRequestInterface $request
?string
Reads the first Content-Type header, strips parameters after ;, and returns the lowercase trimmed media type string or null.
disableXmlEntityLoader(protected static)
bool $disable
bool
No-op returning true on LIBXML_VERSION >= 20900 (where external entities are disabled by default); calls libxml_disable_entity_loader($disable) on older libxml builds.
ContentLengthMiddleware is an outbound post-processing middleware that inspects the ResponseInterface returned by $handler->handle($request) and automatically attaches a Content-Length header if $response->getBody()->getSize() is non-null and no Content-Length header is already present.
Calls $handler->handle($request), checks $response->getBody()->getSize(), and adds Content-Length: (string) $size if $size !== null and !$response->hasHeader('Content-Length').
use Slim\Factory\AppFactory;use Slim\Middleware\ContentLengthMiddleware;$app = AppFactory::create();// Add near the outside of the middleware stack so all responses receive Content-Length:$app->add(new ContentLengthMiddleware());
MethodOverrideMiddleware allows HTML forms and restricted HTTP clients to tunnel PUT, PATCH, or DELETE requests over POST or custom headers. It checks the X-Http-Method-Override request header first; if absent and the request method is POST, it checks $request->getParsedBody()['_METHOD'] and rewinds the request body stream if EOF was reached.
[!IMPORTANT]
When using the POST body _METHOD parameter with application/x-www-form-urlencoded or application/json payloads, BodyParsingMiddleware must execute beforeMethodOverrideMiddleware, and MethodOverrideMiddleware must execute beforeRoutingMiddleware. Because Slim's middleware stack is LIFO, register them in reverse order: addRoutingMiddleware(), then add(MethodOverrideMiddleware), then addBodyParsingMiddleware().
Overrides $request method via $request->withMethod(...) when X-Http-Method-Override header is present or when a POST request's parsed body array contains a non-empty string _METHOD, then delegates to $handler->handle($request).
OutputBufferingMiddleware captures any stray PHP output (echo, print, var_dump) emitted during downstream middleware and route execution using ob_start() and ob_get_clean(), and either appends or prepends the captured buffer to the PSR-7 ResponseInterface body. If an exception is thrown downstream, it safely cleans the buffer with ob_end_clean() before rethrowing.
Initializes the middleware with a PSR-17 StreamFactoryInterface and buffer style. Throws InvalidArgumentException if $style is neither 'append' nor 'prepend'.
Starts an output buffer (ob_start()), invokes $handler->handle($request), collects buffered output (ob_get_clean()), and appends or prepends non-empty output onto $response. Cleans buffer (ob_end_clean()) and rethrows on any Throwable.