Skip to content

Routing

Technomantus Corvi edited this page Sep 5, 2026 · 1 revision

Routing

Format

// routes.php
return [
    'GET  /path'        => 'MyController@method',
    'POST /path'        => 'MyController@store',
    'PUT  /path/{id}'   => 'MyController@update',
    'DELETE /path/{id}' => 'MyController@destroy',
];

Watch your spacing. Route keys are compared as exact strings ("GET /path"), so an extra space for column alignment ('GET /path') silently breaks the match — you get a 404 with no error. Keep exactly one space between the method and the path.

Route parameters

Segments wrapped in {name} are captured and passed as method arguments:

// routes.php
'GET /articles/{slug}' => 'ArticleController@show',

// ArticleController.php
public function show(string $slug): void { /* ... */ }

Order matters

More specific literal routes must come before dynamic patterns that could match the same URL:

'GET /todo/create'  => 'TodoController@create', // must come first
'GET /todo/{id}'     => 'TodoController@show',   // otherwise this catches "create" as an id

Method override (PUT/DELETE from HTML forms)

Browsers only send GET and POST natively. To use PUT/DELETE from a plain HTML form:

<form method="POST" action="/todo/42">
    <input type="hidden" name="_method" value="DELETE">
    <button type="submit">Delete</button>
</form>

The request lifecycle

Browser → public/index.php → App::run()
│
├── loadEnv() Reads .env → $_ENV
├── registerAutoloader() Finds classes in core/, controllers/, models/
├── configureErrors() Debug on/off based on APP_DEBUG
└── dispatch()
│
├── Detects HTTP method (+ _method override)
├── Normalizes the URI
├── (if tanuki_language_selector-style prefix present) strips /xx/ and sets locale
├── Matches an exact route or a {param} pattern
└── Instantiates the Controller → calls method($params)
│
└── $this->view('name', $data)

Language-prefixed routes

If you're using the Internationalization URL switcher (/en/todo, /es/todo), you don't need to duplicate routes with a language segment — the router strips a recognized /xx/ prefix before matching against routes.php, so a single 'GET /todo' entry works for every enabled language.

Adding a new resource

  1. SQL table in your database.
  2. models/YourModel.php — see Models.
  3. Routes in routes.php.
  4. controllers/YourController.php — see Controllers & Requests.
  5. Views in views/your-resource/ — see Views & Layout.

Clone this wiki locally