Request/Response Lifecycle

There's no framework kernel object orchestrating a request behind the scenes — the lifecycle is just the handful of calls public/index.php makes, in order, on values it owns. Here's this site's own front controller, unedited:

require __DIR__ . '/../config/bootstrap.php';

require __DIR__ . '/../app/routes/web.php';
require __DIR__ . '/../app/routes/api.php';

$request = Request::capture();

Route::dispatch($request)->send();

Step by step

  1. config/bootstrap.php — the one shared boot path for web, CLI, and scripts. Loads .env, configures DB, Session, View, and registers Mediator's error/exception/shutdown handlers.
  2. Route registrationapp/routes/web.php and app/routes/api.php run, building the route table via Route::get()/post()/etc. Nothing is matched yet.
  3. Request::capture() — reads PHP's superglobals ($_GET, $_POST, $_SERVER, $_COOKIE, $_FILES, the raw request body) once, into an immutable Request value object.
  4. Route::dispatch($request) — matches the request's path and method against the route table (see Routing for the 404-vs-405 distinction), runs the matched route's middleware pipeline (see Middleware Pipeline), then calls the route's action with the matched parameters followed by the Request itself. Whatever the action returns — a Response, or a plain array (converted to a JSON response) — is what dispatch() returns.
  5. ->send() — emits the HTTP status line, headers, and body. Doesn't exit; the script simply ends normally afterward.

The error path

Mediator::register() (called once, from config/bootstrap.php) installs PHP error, exception, and shutdown handlers. If anything in the request path throws — inside a middleware, inside the action, anywhere — Mediator catches it and renders one of two outputs depending on the configured environment: a development renderer (exception class, message, file/line, source excerpt, ordered stack frames) or a production renderer (internals hidden, an appropriate HTTP status, the full exception recorded via the Logger middleware, and a request/incident ID returned to the caller). Either way, a response still gets sent — a thrown exception never results in a blank page or a raw PHP error dump.

Next steps

  • Routing — how dispatch() matches a route.
  • Middleware Pipeline — what runs between the match and the action.
  • PSR-7 Bridge — converting Request/Response to and from PSR-7, if something in your stack needs it.