Core Application & Bootstrap Factories
Reference for the 7 core runtime and bootstrap classes in Slim\ and Slim\Factory\: Slim\App, Slim\Factory\AppFactory, Slim\Factory\ServerRequestCreatorFactory, Slim\CallableResolver, Slim\MiddlewareDispatcher, Slim\ResponseEmitter, and Slim\Logger.
Source Code
from drawlib.canvas import save, setup
from drawlib.diagrams.architecture import ArchitectureDiagram, Node, NodeGroup, PhosphorIcon
from drawlib.styles import Styles
setup(width=148, height=78)
d = ArchitectureDiagram(
node_style=Styles.Dark,
node_text_style=Styles.DarkBold.patch(text_size=10.2),
edge_style=Styles.Dark.patch(line_width=1.4),
edge_text_style=Styles.Muted.patch(text_size=9.5),
node_card_style=Styles.Neutral,
)
fac_grp = d.add(
NodeGroup(
"Slim\\Factory (Static Bootstrap)",
width=40,
height=68,
style=Styles.PrimaryNeutral,
text_style=Styles.DarkBold.patch(text_size=10.5, halign="left", valign="top"),
),
xy=(4, 5),
)
app_fac = fac_grp.add(
Node(
"AppFactory\n::create()",
icon=PhosphorIcon.FACTORY,
width=32,
height=17,
card_style=Styles.Neutral,
),
xy=(20, 46),
)
req_fac = fac_grp.add(
Node(
"ServerRequestCreator\nFactory::create()",
icon=PhosphorIcon.GLOBE,
width=32,
height=17,
card_style=Styles.Neutral,
),
xy=(20, 18),
)
core_grp = d.add(
NodeGroup(
"Slim\\ (Application Kernel & Collaborators)",
width=92,
height=68,
style=Styles.SecondaryNeutral,
text_style=Styles.DarkBold.patch(text_size=10.5, halign="left", valign="top"),
),
xy=(52, 5),
)
app_node = core_grp.add(
Node(
"Slim\\App\n(RouteCollectorProxy)",
icon=PhosphorIcon.CPU,
width=32,
height=17,
style=Styles.White,
text_style=Styles.WhiteBold.patch(text_size=10.2),
card_style=Styles.PrimaryFlat,
),
xy=(21, 46),
)
emitter_node = core_grp.add(
Node(
"ResponseEmitter\n::emit(response)",
icon=PhosphorIcon.BROADCAST,
width=32,
height=17,
card_style=Styles.Neutral,
),
xy=(21, 18),
)
mw_disp = core_grp.add(
Node(
"MiddlewareDispatcher\n(LIFO Stack)",
icon=PhosphorIcon.STACK,
width=34,
height=14,
card_style=Styles.PrimaryNeutral,
),
xy=(69, 52),
)
resolver = core_grp.add(
Node(
"CallableResolver\n('Class:method' / DI)",
icon=PhosphorIcon.PLUGS_CONNECTED,
width=34,
height=14,
card_style=Styles.Neutral,
),
xy=(69, 32),
)
logger = core_grp.add(
Node(
"Slim\\Logger\n(PSR-3 error_log)",
icon=PhosphorIcon.TERMINAL_WINDOW,
width=34,
height=14,
card_style=Styles.Neutral,
),
xy=(69, 12),
)
app_fac.connect(app_node, label="wires")
req_fac.connect(app_node, label="Request")
app_node.connect(mw_disp, label="handle()")
app_node.connect(emitter_node, label="run()")
mw_disp.connect(resolver, label="resolves")
app_node.connect(logger, label="logs")
d.draw(xy=(0, 0))
save()
classSlim\App#
- Source File:
Slim/App.php - Namespace:
Slim - Extends:
Slim\Routing\RouteCollectorProxy(which implementsRouteCollectorProxyInterface) - Implements:
Psr\Http\Server\RequestHandlerInterface - Template Annotation:
@template TContainerInterface of (ContainerInterface|null)
Slim\App is the central application kernel in Slim 4. By extending RouteCollectorProxy, it exposes all route registration methods (get(), post(), put(), delete(), options(), patch(), any(), map(), group(), redirect()) directly on $app, while implementing PSR-15's RequestHandlerInterface so the entire application can be composed inside outer PSR-15 runners or invoked directly in tests via $app->handle($request).
PHP Class Signature (Slim\App)#
namespace Slim;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Psr\Log\LoggerInterface;
use Slim\Interfaces\CallableResolverInterface;
use Slim\Interfaces\MiddlewareDispatcherInterface;
use Slim\Interfaces\RouteCollectorInterface;
use Slim\Interfaces\RouteResolverInterface;
use Slim\Middleware\BodyParsingMiddleware;
use Slim\Middleware\ErrorMiddleware;
use Slim\Middleware\RoutingMiddleware;
use Slim\Routing\RouteCollectorProxy;
class App extends RouteCollectorProxy implements RequestHandlerInterface
{
public const VERSION = '4.15.1';
protected RouteResolverInterface $routeResolver;
protected MiddlewareDispatcherInterface $middlewareDispatcher;
public function __construct(
ResponseFactoryInterface $responseFactory,
?ContainerInterface $container = null,
?CallableResolverInterface $callableResolver = null,
?RouteCollectorInterface $routeCollector = null,
?RouteResolverInterface $routeResolver = null,
?MiddlewareDispatcherInterface $middlewareDispatcher = null
);
public function getRouteResolver(): RouteResolverInterface;
public function getMiddlewareDispatcher(): MiddlewareDispatcherInterface;
public function add($middleware): self;
public function addMiddleware(MiddlewareInterface $middleware): self;
public function addRoutingMiddleware(): RoutingMiddleware;
public function addErrorMiddleware(
bool $displayErrorDetails,
bool $logErrors,
bool $logErrorDetails,
?LoggerInterface $logger = null
): ErrorMiddleware;
public function addBodyParsingMiddleware(array $bodyParsers = []): BodyParsingMiddleware;
public function run(?ServerRequestInterface $request = null): void;
public function handle(ServerRequestInterface $request): ResponseInterface;
}
Constants & Properties (Slim\App)#
| Member | Visibility & Type | Default / Value | Description |
|---|---|---|---|
VERSION |
public const string |
'4.15.1' |
Version constant defined in Slim\App. |
$routeResolver |
protected RouteResolverInterface |
new RouteResolver($this->routeCollector) |
Resolves URI/method routing results against the RouteCollector. |
$middlewareDispatcher |
protected MiddlewareDispatcherInterface |
new MiddlewareDispatcher($routeRunner, ...) |
LIFO middleware stack seeded with an internal RouteRunner kernel. |
$responseFactory |
protected ResponseFactoryInterface |
(Inherited from RouteCollectorProxy) |
PSR-17 factory used to create fresh ResponseInterface objects and empty HEAD streams. |
$callableResolver |
protected CallableResolverInterface |
(Inherited from RouteCollectorProxy) |
Resolves route and middleware callables. |
$container |
protected ?ContainerInterface |
(Inherited from RouteCollectorProxy) |
Optional PSR-11 dependency injection container. |
$routeCollector |
protected RouteCollectorInterface |
(Inherited from RouteCollectorProxy) |
Underlying route registry (Slim\Routing\RouteCollector by default). |
Constructor & Methods (Slim\App)#
| Method | Parameters | Return Type | Behavior & Notes |
|---|---|---|---|
__construct(...) |
ResponseFactoryInterface $responseFactory, ?ContainerInterface $container = null, ?CallableResolverInterface $callableResolver = null, ?RouteCollectorInterface $routeCollector = null, ?RouteResolverInterface $routeResolver = null, ?MiddlewareDispatcherInterface $middlewareDispatcher = null |
void |
Initializes RouteCollectorProxy, creates default CallableResolver, RouteResolver, and RouteRunner if omitted, and seeds $middlewareDispatcher with $routeRunner. |
getRouteResolver() |
(none) | RouteResolverInterface |
Returns the active route resolver instance. |
getMiddlewareDispatcher() |
(none) | MiddlewareDispatcherInterface |
Returns the application's LIFO middleware dispatcher. |
add($middleware) |
MiddlewareInterface|string|callable $middleware |
self (App<TContainerInterface>) |
Pushes a PSR-15 middleware instance, container/class string, or callable onto the outer layer of the LIFO middleware stack. |
addMiddleware($middleware) |
MiddlewareInterface $middleware |
self (App<TContainerInterface>) |
Pushes a typed Psr\Http\Server\MiddlewareInterface instance onto the middleware stack. |
addRoutingMiddleware() |
(none) | RoutingMiddleware |
Instantiates RoutingMiddleware($this->getRouteResolver(), $this->getRouteCollector()->getRouteParser()), registers it via $this->add(), and returns it so you can position routing explicitly before middlewares that read RouteContext. |
addErrorMiddleware(...) |
bool $displayErrorDetails, bool $logErrors, bool $logErrorDetails, ?LoggerInterface $logger = null |
ErrorMiddleware |
Instantiates ErrorMiddleware, registers it via $this->add() (should be added last so it executes outermost), and returns it for custom handler/renderer configuration. |
addBodyParsingMiddleware(...) |
callable[] $bodyParsers = [] |
BodyParsingMiddleware |
Instantiates BodyParsingMiddleware($bodyParsers), registers it via $this->add(), and returns it. |
run($request) |
?ServerRequestInterface $request = null |
void |
Auto-creates $request from globals via ServerRequestCreatorFactory::create() if null, invokes $this->handle($request), and emits the response via new ResponseEmitter(). |
handle($request) |
ServerRequestInterface $request |
ResponseInterface |
Executes $this->middlewareDispatcher->handle($request). If strtoupper($request->getMethod()) === 'HEAD', replaces the body with an empty stream ($this->responseFactory->createResponse()->getBody()) for RFC 2616 §9.4 compliance. |
(Inherited routing proxy methods get(), post(), put(), delete(), options(), patch(), any(), map(), group(), redirect(), getBasePath(), setBasePath(), getResponseFactory(), getCallableResolver(), getContainer(), and getRouteCollector() are documented under Slim\Routing\RouteCollectorProxy.)
Source Code
from drawlib.canvas import save, setup
from drawlib.diagrams.sequence import Participant, PhosphorIcon, SequenceDiagram
from drawlib.styles import Styles
setup(width=144, height=96)
sd = SequenceDiagram(
node_style=Styles.Dark,
node_text_style=Styles.DarkBold.patch(text_size=10.0),
edge_style=Styles.Dark.patch(line_width=1.4),
edge_text_style=Styles.Dark.patch(text_size=9.5),
node_card_style=Styles.Neutral,
col_width=34.0,
step_y=6.5,
)
p_client = sd.add(Participant("index.php", icon=PhosphorIcon.FILE_CODE, width=24, card_style=Styles.PrimaryNeutral))
p_app = sd.add(
Participant(
"Slim\\App",
icon=PhosphorIcon.CPU,
width=24,
style=Styles.White,
text_style=Styles.WhiteBold.patch(text_size=10.0),
card_style=Styles.PrimaryFlat,
)
)
p_mw = sd.add(Participant("MiddlewareDispatcher", icon=PhosphorIcon.STACK, width=28, card_style=Styles.SecondaryNeutral))
p_emit = sd.add(Participant("ResponseEmitter", icon=PhosphorIcon.BROADCAST, width=26, card_style=Styles.Neutral))
p_client.request(p_app, "1. run(request = null)")
p_app.request(p_app, "2. createServerRequestFromGlobals()")
p_app.request(p_mw, "3. handle(ServerRequestInterface)")
p_mw.reply(p_app, "4. ResponseInterface (LIFO + RouteRunner)")
p_app.request(p_app, "5. If HEAD -> withBody(emptyStream)")
p_app.request(p_emit, "6. emit(response): headers, status, body")
p_emit.reply(p_client, "7. Stream HTTP Response to SAPI")
sd.draw(xy=(72, 48), align="center")
save()
Usage Example (Slim\App)#
<?php
declare(strict_types=1);
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;
$app = AppFactory::create();
// 1. Parse JSON / form / XML request bodies
$app->addBodyParsingMiddleware();
// 2. Explicit routing middleware (placed before custom middlewares that inspect RouteContext)
$app->addRoutingMiddleware();
// 3. Outermost error middleware (added last -> executed first in LIFO order)
$errorMiddleware = $app->addErrorMiddleware(true, true, true);
$app->get('/health', function (Request $request, Response $response): Response {
$payload = json_encode(['status' => 'ok', 'slim' => $this::VERSION], JSON_THROW_ON_ERROR);
$response->getBody()->write($payload);
return $response->withHeader('Content-Type', 'application/json');
});
$app->run();
classSlim\Factory\AppFactory#
- Source File:
Slim/Factory/AppFactory.php - Namespace:
Slim\Factory
AppFactory is a static builder class that constructs Slim\App instances without requiring manual instantiation of a ResponseFactoryInterface. When AppFactory::create() or AppFactory::createFromContainer($container) is called, it either uses a pre-configured ResponseFactoryInterface, resolves one from the PSR-11 container, or queries Psr17FactoryProvider to auto-detect an installed PSR-17 implementation (and automatically decorates it with Slim\Http\Factory\DecoratedResponseFactory if slim/http is installed and $slimHttpDecoratorsAutomaticDetectionEnabled is true).
PHP Class Signature (Slim\Factory\AppFactory)#
namespace Slim\Factory;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\StreamFactoryInterface;
use RuntimeException;
use Slim\App;
use Slim\Interfaces\CallableResolverInterface;
use Slim\Interfaces\MiddlewareDispatcherInterface;
use Slim\Interfaces\Psr17FactoryProviderInterface;
use Slim\Interfaces\RouteCollectorInterface;
use Slim\Interfaces\RouteResolverInterface;
class AppFactory
{
protected static ?Psr17FactoryProviderInterface $psr17FactoryProvider = null;
protected static ?ResponseFactoryInterface $responseFactory = null;
protected static ?StreamFactoryInterface $streamFactory = null;
protected static ?ContainerInterface $container = null;
protected static ?CallableResolverInterface $callableResolver = null;
protected static ?RouteCollectorInterface $routeCollector = null;
protected static ?RouteResolverInterface $routeResolver = null;
protected static ?MiddlewareDispatcherInterface $middlewareDispatcher = null;
protected static bool $slimHttpDecoratorsAutomaticDetectionEnabled = true;
public static function create(
?ResponseFactoryInterface $responseFactory = null,
?ContainerInterface $container = null,
?CallableResolverInterface $callableResolver = null,
?RouteCollectorInterface $routeCollector = null,
?RouteResolverInterface $routeResolver = null,
?MiddlewareDispatcherInterface $middlewareDispatcher = null
): App;
public static function createFromContainer(ContainerInterface $container): App;
public static function determineResponseFactory(): ResponseFactoryInterface;
protected static function attemptResponseFactoryDecoration(
ResponseFactoryInterface $responseFactory,
StreamFactoryInterface $streamFactory
): ResponseFactoryInterface;
public static function setPsr17FactoryProvider(Psr17FactoryProviderInterface $psr17FactoryProvider): void;
public static function setResponseFactory(ResponseFactoryInterface $responseFactory): void;
public static function setStreamFactory(StreamFactoryInterface $streamFactory): void;
public static function setContainer(ContainerInterface $container): void;
public static function setCallableResolver(CallableResolverInterface $callableResolver): void;
public static function setRouteCollector(RouteCollectorInterface $routeCollector): void;
public static function setRouteResolver(RouteResolverInterface $routeResolver): void;
public static function setMiddlewareDispatcher(MiddlewareDispatcherInterface $middlewareDispatcher): void;
public static function setSlimHttpDecoratorsAutomaticDetection(bool $enabled): void;
}
Static Methods (Slim\Factory\AppFactory)#
| Method | Parameters | Return Type | Description |
|---|---|---|---|
create(...) |
?ResponseFactoryInterface $responseFactory = null, ?ContainerInterface $container = null, ?CallableResolverInterface $callableResolver = null, ?RouteCollectorInterface $routeCollector = null, ?RouteResolverInterface $routeResolver = null, ?MiddlewareDispatcherInterface $middlewareDispatcher = null |
App |
Creates a new App merging explicit arguments with static properties and calling self::determineResponseFactory(). |
createFromContainer($container) |
ContainerInterface $container |
App |
Inspects $container->has(...) for ResponseFactoryInterface, CallableResolverInterface, RouteCollectorInterface, RouteResolverInterface, and MiddlewareDispatcherInterface (falling back to determineResponseFactory() / null), then returns new App(...). |
determineResponseFactory() |
(none) | ResponseFactoryInterface |
Returns static::$responseFactory (decorated if static::$streamFactory is set), or loops over Psr17FactoryProvider::getFactories() to instantiate the first available ResponseFactoryInterface. Throws RuntimeException if none is found. |
attemptResponseFactoryDecoration(...) (protected) |
ResponseFactoryInterface $responseFactory, StreamFactoryInterface $streamFactory |
ResponseFactoryInterface |
Wraps $responseFactory and $streamFactory via SlimHttpPsr17Factory::createDecoratedResponseFactory() when slim/http is installed and auto-detection is enabled. |
setPsr17FactoryProvider($provider) |
Psr17FactoryProviderInterface $psr17FactoryProvider |
void |
Overrides the static Psr17FactoryProviderInterface used during auto-discovery. |
setResponseFactory($responseFactory) |
ResponseFactoryInterface $responseFactory |
void |
Sets the default static ResponseFactoryInterface for subsequent create() calls. |
setStreamFactory($streamFactory) |
StreamFactoryInterface $streamFactory |
void |
Sets the default static StreamFactoryInterface used when decorating with slim/http. |
setContainer($container) |
ContainerInterface $container |
void |
Sets the default static PSR-11 ContainerInterface for subsequent create() calls. |
setCallableResolver($callableResolver) |
CallableResolverInterface $callableResolver |
void |
Sets the default static CallableResolverInterface. |
setRouteCollector($routeCollector) |
RouteCollectorInterface $routeCollector |
void |
Sets the default static RouteCollectorInterface. |
setRouteResolver($routeResolver) |
RouteResolverInterface $routeResolver |
void |
Sets the default static RouteResolverInterface. |
setMiddlewareDispatcher($middlewareDispatcher) |
MiddlewareDispatcherInterface $middlewareDispatcher |
void |
Sets the default static MiddlewareDispatcherInterface. |
setSlimHttpDecoratorsAutomaticDetection($enabled) |
bool $enabled |
void |
Enables (true) or disables (false) automatic wrapping with slim/http response decorators. |
Usage Example (Slim\Factory\AppFactory)#
<?php
declare(strict_types=1);
use DI\Container;
use Slim\Factory\AppFactory;
// Option A: Configure static container then call create()
$container = new Container();
AppFactory::setContainer($container);
AppFactory::setSlimHttpDecoratorsAutomaticDetection(false);
$app = AppFactory::create();
// Option B: Resolve core services directly from a PSR-11 container
$appFromDi = AppFactory::createFromContainer($container);
classSlim\Factory\ServerRequestCreatorFactory#
- Source File:
Slim/Factory/ServerRequestCreatorFactory.php - Namespace:
Slim\Factory
ServerRequestCreatorFactory is the static counterpart to AppFactory for incoming HTTP requests. Called automatically by App::run() when no ServerRequestInterface is passed, it probes Psr17FactoryProvider to locate a vendor ServerRequestCreatorInterface capable of building a PSR-7 ServerRequestInterface from PHP superglobals, and optionally wraps it in SlimHttpServerRequestCreator if slim/http is present.
PHP Class Signature (Slim\Factory\ServerRequestCreatorFactory)#
namespace Slim\Factory;
use RuntimeException;
use Slim\Interfaces\Psr17FactoryProviderInterface;
use Slim\Interfaces\ServerRequestCreatorInterface;
class ServerRequestCreatorFactory
{
protected static ?Psr17FactoryProviderInterface $psr17FactoryProvider = null;
protected static ?ServerRequestCreatorInterface $serverRequestCreator = null;
protected static bool $slimHttpDecoratorsAutomaticDetectionEnabled = true;
public static function create(): ServerRequestCreatorInterface;
public static function determineServerRequestCreator(): ServerRequestCreatorInterface;
protected static function attemptServerRequestCreatorDecoration(
ServerRequestCreatorInterface $serverRequestCreator
): ServerRequestCreatorInterface;
public static function setPsr17FactoryProvider(Psr17FactoryProviderInterface $psr17FactoryProvider): void;
public static function setServerRequestCreator(ServerRequestCreatorInterface $serverRequestCreator): void;
public static function setSlimHttpDecoratorsAutomaticDetection(bool $enabled): void;
}
Static Methods (Slim\Factory\ServerRequestCreatorFactory)#
| Method | Parameters | Return Type | Description |
|---|---|---|---|
create() |
(none) | ServerRequestCreatorInterface |
Alias for static::determineServerRequestCreator(). |
determineServerRequestCreator() |
(none) | ServerRequestCreatorInterface |
Returns static::$serverRequestCreator if set, or iterates Psr17FactoryProvider::getFactories() and returns the first available getServerRequestCreator() (wrapped with attemptServerRequestCreatorDecoration()). Throws RuntimeException if none is available. |
attemptServerRequestCreatorDecoration(...) (protected) |
ServerRequestCreatorInterface $serverRequestCreator |
ServerRequestCreatorInterface |
Wraps $serverRequestCreator in new SlimHttpServerRequestCreator($serverRequestCreator) if automatic detection is enabled and Slim\Http\ServerRequest exists. |
setPsr17FactoryProvider($provider) |
Psr17FactoryProviderInterface $psr17FactoryProvider |
void |
Overrides the Psr17FactoryProviderInterface registry. |
setServerRequestCreator($creator) |
ServerRequestCreatorInterface $serverRequestCreator |
void |
Explicitly sets a custom ServerRequestCreatorInterface instance. |
setSlimHttpDecoratorsAutomaticDetection($enabled) |
bool $enabled |
void |
Enables or disables automatic Slim\Http\ServerRequest decoration. |
Usage Example (Slim\Factory\ServerRequestCreatorFactory)#
<?php
declare(strict_types=1);
use Slim\Factory\AppFactory;
use Slim\Factory\ServerRequestCreatorFactory;
// Create a PSR-7 ServerRequest from PHP globals manually before running the app
$creator = ServerRequestCreatorFactory::create();
$request = $creator->createServerRequestFromGlobals();
$app = AppFactory::create();
$response = $app->handle($request);
classSlim\CallableResolver#
- Source File:
Slim/CallableResolver.php - Namespace:
Slim - Modifiers:
final class - Implements:
Slim\Interfaces\AdvancedCallableResolverInterface(which extendsCallableResolverInterface) - Template Annotation:
@template TContainerInterface of (ContainerInterface|null)
CallableResolver translates Slim's flexible callable notations into executable PHP callables. It supports:
- Native PHP callables (
Closure, function names, invokable objects,[$object, 'method']). [ClassName::class, 'method']two-element arrays (normalized to'ClassName:method').- Slim colon notation
'ClassName:method'matched byCallableResolver::$callablePattern(!^([^\:]+)\:([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)$!). - Container service IDs or class names: resolved from
$this->container->get($class)if registered in the PSR-11 container, or instantiated vianew $class($this->container)otherwise. - Automatic default method selection:
resolveRoute()defaultsRequestHandlerInterfaceinstances to'handle',resolveMiddleware()defaultsMiddlewareInterfaceinstances to'process', andresolve()defaults to'__invoke'. - Closure binding: if
$this->containeris present and the resolved callable is aClosure, it binds$thisinside the closure via$callable->bindTo($this->container).
PHP Class Signature (Slim\CallableResolver)#
namespace Slim;
use Psr\Container\ContainerInterface;
use Slim\Interfaces\AdvancedCallableResolverInterface;
final class CallableResolver implements AdvancedCallableResolverInterface
{
public static string $callablePattern = '!^([^\:]+)\:([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)$!';
private ?ContainerInterface $container;
public function __construct(?ContainerInterface $container = null);
public function resolve($toResolve): callable;
public function resolveRoute($toResolve): callable;
public function resolveMiddleware($toResolve): callable;
}
Properties & Methods (Slim\CallableResolver)#
| Member / Method | Signature / Type | Return Type | Description |
|---|---|---|---|
$callablePattern |
public static string |
string |
Regex pattern matching 'class:method' strings (!^([^\:]+)\:([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)$!). |
__construct($container) |
?ContainerInterface $container = null |
void |
Stores the optional PSR-11 container used for service resolution and Closure::bindTo(). |
resolve($toResolve) |
string|callable $toResolve |
callable |
Resolves a generic callable, defaulting class strings without a method to '__invoke'. Throws RuntimeException if unresolvable. |
resolveRoute($toResolve) |
string|callable $toResolve |
callable |
Resolves a route callable; if the target object implements Psr\Http\Server\RequestHandlerInterface and no method is specified, resolves [$instance, 'handle']. |
resolveMiddleware($toResolve) |
string|callable $toResolve |
callable |
Resolves a middleware callable; if the target object implements Psr\Http\Server\MiddlewareInterface and no method is specified, resolves [$instance, 'process']. |
Usage Example (Slim\CallableResolver)#
<?php
declare(strict_types=1);
use Slim\CallableResolver;
$resolver = new CallableResolver($container);
// Resolve 'Class:method' string, [Class::class, 'method'] array, or PSR-15 RequestHandlerInterface
$routeCallable = $resolver->resolveRoute('App\Action\UserListAction:index');
$handlerCallable = $resolver->resolveRoute(\App\Action\SingleActionHandler::class); // -> [$instance, 'handle']
$mwCallable = $resolver->resolveMiddleware(\App\Middleware\AuthMiddleware::class); // -> [$instance, 'process']
classSlim\MiddlewareDispatcher#
- Source File:
Slim/MiddlewareDispatcher.php - Namespace:
Slim - Implements:
Slim\Interfaces\MiddlewareDispatcherInterface(which extendsPsr\Http\Server\RequestHandlerInterface) - Template Annotation:
@template TContainerInterface of (ContainerInterface|null)
MiddlewareDispatcher implements Slim 4's concentric LIFO (Last-In, First-Out) middleware stack. It wraps a core RequestHandlerInterface $kernel (RouteRunner at the application level, or Route at the route level) in lightweight anonymous RequestHandlerInterface decorators. Every call to add(), addMiddleware(), addDeferred(), or addCallable() replaces $this->tip with a new outer handler pointing $next to the previous $this->tip.
PHP Class Signature (Slim\MiddlewareDispatcher)#
namespace Slim;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Slim\Interfaces\CallableResolverInterface;
use Slim\Interfaces\MiddlewareDispatcherInterface;
class MiddlewareDispatcher implements MiddlewareDispatcherInterface
{
protected RequestHandlerInterface $tip;
protected ?CallableResolverInterface $callableResolver;
protected ?ContainerInterface $container;
public function __construct(
RequestHandlerInterface $kernel,
?CallableResolverInterface $callableResolver = null,
?ContainerInterface $container = null
);
public function seedMiddlewareStack(RequestHandlerInterface $kernel): void;
public function handle(ServerRequestInterface $request): ResponseInterface;
public function add($middleware): MiddlewareDispatcherInterface;
public function addMiddleware(MiddlewareInterface $middleware): MiddlewareDispatcherInterface;
public function addDeferred(string $middleware): self;
public function addCallable(callable $middleware): self;
}
Constructor & Methods (Slim\MiddlewareDispatcher)#
| Method | Parameters | Return Type | Description |
|---|---|---|---|
__construct(...) |
RequestHandlerInterface $kernel, ?CallableResolverInterface $callableResolver = null, ?ContainerInterface $container = null |
void |
Calls seedMiddlewareStack($kernel) and stores $callableResolver and $container. |
seedMiddlewareStack($kernel) |
RequestHandlerInterface $kernel |
void |
Sets $this->tip = $kernel as the innermost request handler of the stack. |
handle($request) |
ServerRequestInterface $request |
ResponseInterface |
Invokes $this->tip->handle($request) to traverse the middleware stack from outermost to innermost. |
add($middleware) |
MiddlewareInterface|string|callable $middleware |
MiddlewareDispatcherInterface |
Dispatches to addMiddleware() for MiddlewareInterface, addDeferred() for string, or addCallable() for callable. Throws RuntimeException otherwise. |
addMiddleware($middleware) |
MiddlewareInterface $middleware |
MiddlewareDispatcherInterface |
Wraps $this->tip in an anonymous RequestHandlerInterface that calls $middleware->process($request, $this->next). |
addDeferred($middleware) |
string $middleware |
self |
Wraps $this->tip in a lazy anonymous RequestHandlerInterface that resolves $middleware via AdvancedCallableResolverInterface::resolveMiddleware() (or container / class:method fallback) only when handle() is actually invoked. |
addCallable($middleware) |
callable $middleware |
self |
Binds Closure middlewares to $this->container if present and wraps $this->tip in an anonymous RequestHandlerInterface invoking ($this->middleware)($request, $this->next). |
Usage Example (Slim\MiddlewareDispatcher)#
<?php
declare(strict_types=1);
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
// Adding middlewares to $app delegates to MiddlewareDispatcher::add()
// LIFO order: OuterMiddleware runs BEFORE InnerMiddleware
$app->add(function (Request $request, RequestHandler $handler): Response {
$response = $handler->handle($request->withAttribute('inner', true));
return $response->withHeader('X-Inner-Middleware', '1');
});
$app->add('App\Middleware\OuterAuthMiddleware'); // Deferred resolution on handle()
classSlim\ResponseEmitter#
- Source File:
Slim/ResponseEmitter.php - Namespace:
Slim
ResponseEmitter streams a PSR-7 ResponseInterface to the PHP SAPI output buffer. It includes three important HTTP edge-case safeguards:
- Multi-Value
Set-CookiePreservation: InemitHeaders(), all headers replace previous values on their first iteration ($first = true) exceptset-cookie(strtolower($name) !== 'set-cookie'), ensuring multipleSet-Cookieheaders are never overwritten. - Status Line Emitted After Headers:
emitStatusLine()is deliberately called afteremitHeaders()to prevent PHP's built-inheader('Location: ...')behavior from overriding an explicit custom redirect status code (e.g.,301,303,307,308) with302(Slim issue #1730). - Empty Status & Chunked Streaming:
isResponseEmpty()suppresses body output on204 No Content,205 Reset Content, and304 Not Modified(or empty streams), whileemitBody()streams bodies in$responseChunkSize(4096-byte) chunks and halts early ifconnection_status() !== CONNECTION_NORMAL.
PHP Class Signature (Slim\ResponseEmitter)#
namespace Slim;
use Psr\Http\Message\ResponseInterface;
class ResponseEmitter
{
private int $responseChunkSize;
public function __construct(int $responseChunkSize = 4096);
public function emit(ResponseInterface $response): void;
public function isResponseEmpty(ResponseInterface $response): bool;
}
Constructor & Methods (Slim\ResponseEmitter)#
| Method | Parameters | Return Type | Description |
|---|---|---|---|
__construct($responseChunkSize) |
int $responseChunkSize = 4096 |
void |
Configures the maximum byte chunk size read per StreamInterface::read() iteration when emitting the response body. |
emit($response) |
ResponseInterface $response |
void |
Checks isResponseEmpty($response), emits headers and status line if headers_sent() === false, and streams the body if non-empty. |
isResponseEmpty($response) |
ResponseInterface $response |
bool |
Returns true if the status code is in [204, 205, 304], or if the response stream is empty (rewinding seekable streams and testing $stream->read(1) === '', or $stream->eof() for non-seekable streams). |
Usage Example (Slim\ResponseEmitter)#
<?php
declare(strict_types=1);
use Slim\Factory\AppFactory;
use Slim\Factory\ServerRequestCreatorFactory;
use Slim\ResponseEmitter;
$app = AppFactory::create();
$request = ServerRequestCreatorFactory::create()->createServerRequestFromGlobals();
$response = $app->handle($request);
// Emit with a custom 8 KB chunk size for large file/stream responses
$emitter = new ResponseEmitter(8192);
$emitter->emit($response);
classSlim\Logger#
- Source File:
Slim/Logger.php - Namespace:
Slim - Extends:
Psr\Log\AbstractLogger(which implementsPsr\Log\LoggerInterface)
Slim\Logger is the zero-configuration fallback PSR-3 logger instantiated by ErrorHandler when no custom Psr\Log\LoggerInterface is provided to App::addErrorMiddleware() or ErrorMiddleware::__construct(). It inherits emergency(), alert(), critical(), error(), warning(), notice(), info(), and debug() from Psr\Log\AbstractLogger and delegates all levels to error_log((string) $message).
PHP Class Signature (Slim\Logger)#
namespace Slim;
use Psr\Log\AbstractLogger;
use Psr\Log\InvalidArgumentException;
use Stringable;
class Logger extends AbstractLogger
{
/**
* @param mixed $level
* @param string|Stringable $message
* @param array<mixed> $context
*
* @throws InvalidArgumentException
*/
public function log($level, $message, array $context = []): void;
}
Methods (Slim\Logger)#
| Method | Parameters | Return Type | Description |
|---|---|---|---|
log($level, $message, $context) |
mixed $level, string|Stringable $message, array<mixed> $context = [] |
void |
Writes (string) $message directly to PHP's error_log(). |
Usage Example (Slim\Logger)#
<?php
declare(strict_types=1);
use Slim\Logger;
$logger = new Logger();
$logger->error('Unhandled exception in checkout pipeline');