Skip to content

Understanding routing

Greg Bowler edited this page Apr 14, 2026 · 1 revision

Routing takes an incoming request and decides which part of the application should handle it.

That sounds straightforward, but in practice there are usually two levels of decision to make:

  1. Which callback should receive the request
  2. Which files make up the response for that request

This library supports both.

Callback routing

At the first level, BaseRouter reflects over the methods on your router class and looks for route attributes.

Each attributed method can match on:

  • HTTP method
  • request path
  • accepted content type

When route() is called, every attributed method is checked. The matching callback is then invoked through the service container injector, so the method can receive services such as the current request, a PathMatcher, or any application service that has been registered.

Assembly-based routing

After a callback has matched, the callback usually adds files to one or both assemblies:

  • A logic assembly for PHP files to execute
  • A view assembly for templates or page fragments to render

The router itself does not execute those files. It only decides what belongs to the request. This keeps routing separate from dispatching and rendering, which can remain the responsibility of the framework.

Request matching order

The matching process is:

  1. Filter by HTTP method
  2. Filter by exact path match
  3. Filter by Accept header compatibility
  4. If more than one callback still matches, choose the best candidate by content negotiation

If nothing matches, BaseRouter::route() throws HttpNotAcceptable.

Redirect handling

Redirects are separate from callback routing. If we have a redirects CSV file, we can load it through Redirects and call handleRedirects() before normal routing begins.

The redirect response code comes from RouterConfig:

  • 300 for HttpMultipleChoices
  • 301 for HttpMovedPermanently
  • 302 for HttpFound
  • 303 for HttpSeeOther
  • 304 for HttpNotModified
  • 307 for HttpTemporaryRedirect
  • Any other configured value falls back to 308 HttpPermanentRedirect

What this library does not do

This repository does not:

  • create the PSR-7 request
  • emit the final response
  • render HTML
  • execute assemblies for you

Those jobs belong to the wider application or framework.


Continue to attribute configuration to see how callbacks are declared.

Clone this wiki locally