Leaf 5 โ Routing Reference โ
Basic Methods โ
php
app()->get('/home', function () { /* ... */ });
app()->post('/home', function () { /* ... */ });
app()->put('/home', function () { /* ... */ });
app()->patch('/home', function () { /* ... */ });
app()->delete('/home', function () { /* ... */ });
app()->options('/home', function () { /* ... */ });
app()->match('GET|POST', '/users', function () { /* ... */ });
app()->run(); // dispatch โ always call at the endControllers (MVC) โ
php
app()->get('/home', 'HomeController@index');
app()->get('/home', ['name' => 'home', 'HomeController@index']);Views & Inertia โ
php
app()->view('/home', 'home'); // configured template engine
app()->inertia('/home', 'Home'); // Inertia (React/Vue/Svelte)404 Handler โ
php
app()->set404(fn () => response()->json(['error' => 'Page not found']));Route Options โ
Pass an array before the handler to set metadata (name, middleware, sitemap options, etc.):
php
app()->get('/home', ['name' => 'home', function () {
$route = app()->getRoute();
// $route: pattern, path, name, method, handler, + any custom options
echo $route['name'];
}]);Named Routes & Redirects โ
php
app()->get('/home', ['name' => 'home', function () { /* ... */ }]);
response()->redirect(['home']); // by route name
response()->redirect('/login'); // by path
response()->redirect('https://x.com'); // external
$route = app()->route('home'); // get route info by nameRoute Groups โ
php
// Basic prefix group
app()->group('/admin', function () {
app()->get('/', function () { echo 'dashboard'; });
app()->get('/users', function () { echo 'users'; });
});
// Group with options (namespace, middleware, etc.)
app()->group('/admin', ['namespace' => 'MyNameSpace', function () {
app()->get('/form', 'FormsController@index'); // โ MyNameSpace\FormsController@index
}]);
// Group with middleware
app()->group('/admin', ['middleware' => 'auth', function () {
app()->get('/', function () { echo 'dashboard'; });
}]);Dynamic Routes โ
php
// Named parameter
app()->get('/movies/{movieId}', function ($id) {
echo 'Movie #' . $id;
});
// Multiple parameters
app()->get('/movies/{foo}/photos/{bar}', function ($movieId, $photoId) {
echo 'Movie #' . $movieId . ', photo #' . $photoId;
});
// Constraint: placeholder must match the regex after the colon
app()->get('/movies/{id:[0-9]+}/photos/{photoId:[0-9]+}', function ($movieId, $photoId) {
echo 'Movie #' . $movieId . ', photo #' . $photoId;
});Raw regex patterns like
/movies/(\d+)are NOT supported in Leaf 5 โ patterns without{}placeholders are treated as literal paths. Always use named placeholders.
Optional Parameters โ
php
// /posts and /posts/1 both match โ give optional params a default value
app()->get('/posts/{id?}', function ($id = null) {
echo $id ? 'Post #' . $id : 'All posts';
});
// Optional + constraint: ? goes after the name, before the constraint
app()->get('/posts/{id?:[0-9]+}', function ($id = null) {
echo $id ? 'Post #' . $id : 'All posts';
});
// Chained optionals
// Matches /blog, /blog/2024, /blog/2024/01, /blog/2024/01/slug
app()->get('/blog/{year?:[0-9]{4}}/{month?:[0-9]{2}}/{slug?}', function (
$year = null, $month = null, $slug = null
) {
if (!$year) { echo 'Blog overview'; return; }
if (!$month) { echo 'Year overview'; return; }
if (!$slug) { echo 'Month overview'; return; }
echo 'Post: ' . htmlentities($slug);
});Matching Order โ
Exact routes always beat dynamic routes regardless of registration order (/users/new wins over /users/{id}). Between overlapping dynamic routes, the one registered first wins โ register more specific dynamic routes before broader ones.
