Routing
Default Routing Rules
The default routing rule for webman is http://127.0.0.1:8787/{controller}/{action}
.
The default controller is app\controller\IndexController
, and the default action is index
.
For example, when accessing:
http://127.0.0.1:8787
, it will by default access theindex
method of theapp\controller\IndexController
class.http://127.0.0.1:8787/foo
, it will by default access theindex
method of theapp\controller\FooController
class.http://127.0.0.1:8787/foo/test
, it will by default access thetest
method of theapp\controller\FooController
class.http://127.0.0.1:8787/admin/foo/test
, it will by default access thetest
method of theapp\admin\controller\FooController
class (see Multiple Applications).
Additionally, starting from webman 1.4, it supports more complex default routing, such as
app
├── admin
│ └── v1
│ └── v2
│ └── v3
│ └── controller
│ └── IndexController.php
└── controller
├── v1
│ └── IndexController.php
└── v2
└── v3
└── IndexController.php
When you want to change a request route, please modify the configuration file config/route.php
.
If you want to disable the default route, add the following configuration to the end of the config/route.php
file:
Route::disableDefaultRoute();
Closure Routes
Add the following route code to config/route.php
:
Route::any('/test', function ($request) {
return response('test');
});
Note
Because closure functions do not belong to any controller,$request->app
,$request->controller
, and$request->action
are all empty strings.
When accessing the address http://127.0.0.1:8787/test
, it will return the string test
.
Note
The route path must start with/
, for example:
// Incorrect usage
Route::any('test', function ($request) {
return response('test');
});
// Correct usage
Route::any('/test', function ($request) {
return response('test');
});
Class Routes
Add the following route code to config/route.php
:
Route::any('/testclass', [app\controller\IndexController::class, 'test']);
When accessing the address http://127.0.0.1:8787/testclass
, it will return the result of the test
method of the app\controller\IndexController
class.
Route Parameters
If there are parameters in the route, they can be matched using {key}
and the matched result will be passed to the corresponding controller method parameter (starting from the second parameter), for example:
// Matching /user/123 /user/abc
Route::any('/user/{id}', [app\controller\UserController::class, 'get']);
namespace app\controller;
class UserController
{
public function get($request, $id)
{
return response('Received parameter'.$id);
}
}
More examples:
// Matching /user/123, not matching /user/abc
Route::any('/user/{id:\d+}', function ($request, $id) {
return response($id);
});
// Matching /user/foobar, not matching /user/foo/bar
Route::any('/user/{name}', function ($request, $name) {
return response($name);
});
// Matching /user, /user/123, and /user/abc
Route::any('/user[/{name}]', function ($request, $name = null) {
return response($name ?? 'tom');
});
// Matching all options requests
Route::options('[{path:.+}]', function () {
return response('');
});
Route Groups
Sometimes, routes contain a lot of the same prefixes. In this case, we can use route groups to simplify the definition. For example:
Route::group('/blog', function () {
Route::any('/create', function ($request) {return response('create');});
Route::any('/edit', function ($request) {return response('edit');});
Route::any('/view/{id}', function ($request, $id) {return response("view $id");});
});
Equivalent to:
Route::any('/blog/create', function ($request) {return response('create');});
Route::any('/blog/edit', function ($request) {return response('edit');});
Route::any('/blog/view/{id}', function ($request, $id) {return response("view $id");});
Nested group
usage:
Route::group('/blog', function () {
Route::group('/v1', function () {
Route::any('/create', function ($request) {return response('create');});
Route::any('/edit', function ($request) {return response('edit');});
Route::any('/view/{id}', function ($request, $id) {return response("view $id");});
});
});
Route Middleware
We can set a middleware for a specific route or a group of routes. For example:
Route::any('/admin', [app\admin\controller\IndexController::classe, 'index'])->middleware([
app\middleware\MiddlewareA::class,
app\middleware\MiddlewareB::class,
]);
Route::group('/blog', function () {
Route::any('/create', function () {return response('create');});
Route::any('/edit', function () {return response('edit');});
Route::any('/view/{id}', function ($request, $id) {response("view $id");});
})->middleware([
app\middleware\MiddlewareA::class,
app\middleware\MiddlewareB::class,
]);
Note:
In webman-framework <= 1.5.6, when the->middleware()
route middleware applies to a group after that, the current route must be within that group.
# Incorrect usage example (this usage is valid in webman-framework >= 1.5.7)
Route::group('/blog', function () {
Route::group('/v1', function () {
Route::any('/create', function ($request) {return response('create');});
Route::any('/edit', function ($request) {return response('edit');});
Route::any('/view/{id}', function ($request, $id) {return response("view $id");});
});
})->middleware([
app\middleware\MiddlewareA::class,
app\middleware\MiddlewareB::class,
]);
# Correct usage example
Route::group('/blog', function () {
Route::group('/v1', function () {
Route::any('/create', function ($request) {return response('create');});
Route::any('/edit', function ($request) {return response('edit');});
Route::any('/view/{id}', function ($request, $id) {return response("view $id");});
})->middleware([
app\middleware\MiddlewareA::class,
app\middleware\MiddlewareB::class,
]);
});
Resourceful Routing
Route::resource('/test', app\controller\IndexController::class);
// Specify resource routes
Route::resource('/test', app\controller\IndexController::class, ['index','create']);
// Non-defining resource routes
// If accessing notify, it will be any type of route /test/notify or /test/notify/{id} and the routeName will be test.notify
Route::resource('/test', app\controller\IndexController::class, ['index','create','notify']);
Verb | URI | Action | Route Name |
---|---|---|---|
GET | /test | index | test.index |
GET | /test/create | create | test.create |
POST | /test | store | test.store |
GET | /test/{id} | show | test.show |
GET | /test/{id}/edit | edit | test.edit |
PUT | /test/{id} | update | test.update |
DELETE | /test/{id} | destroy | test.destroy |
PUT | /test/{id}/recovery | recovery | test.recovery |
URL Generation
Note:
Currently, route generation of nested route groups is not supported
For example, with the route:
Route::any('/blog/{id}', [app\controller\BlogController::class, 'view'])->name('blog.view');
We can use the following method to generate the URL for this route:
route('blog.view', ['id' => 100]); // Result is /blog/100
When using route URLs in a view, this method can be used so that regardless of changes to the routing rules, the URL will be generated automatically, avoiding the need to modify a large number of view files due to changes in route addresses.
Obtain Route Information
Note
Requires webman-framework >= 1.3.2
We can obtain the current request route information through the $request->route
object, for example:
$route = $request->route; // Equivalent to $route = request()->route;
if ($route) {
var_export($route->getPath());
var_export($route->getMethods());
var_export($route->getName());
var_export($route->getMiddleware());
var_export($route->getCallback());
var_export($route->param()); // This feature requires webman-framework >= 1.3.16
}
Note
If the current request does not match any routes configured inconfig/route.php
,$request->route
will be null, meaning that the default route will result in$request->route
being null.
Handling 404 Errors
When the route is not found, the default behavior is to return a 404 status code and output the content of public/404.html
.
If developers want to intervene in the business process when a route is not found, they can use the fallback route provided by webman using the Route::fallback($callback)
method. For example, the following code logic redirects to the homepage when the route is not found.
Route::fallback(function(){
return redirect('/');
});
Another example is returning a JSON response when the route does not exist, which is very useful when webman is used as an API endpoint.
Route::fallback(function(){
return json(['code' => 404, 'msg' => '404 not found']);
});
Related link: Custom 404 and 500 Pages
Route Interface
// Set a route for any method request for $uri
Route::any($uri, $callback);
// Set a route for a get request for $uri
Route::get($uri, $callback);
// Set a route for a post request for $uri
Route::post($uri, $callback);
// Set a route for a put request for $uri
Route::put($uri, $callback);
// Set a route for a patch request for $uri
Route::patch($uri, $callback);
// Set a route for a delete request for $uri
Route::delete($uri, $callback);
// Set a route for a head request for $uri
Route::head($uri, $callback);
// Set routes for multiple request types simultaneously
Route::add(['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'], $uri, $callback);
// Group routes
Route::group($path, $callback);
// Resource routes
Route::resource($path, $callback, [$options]);
// Disable the default route
Route::disableDefaultRoute($plugin = '');
// Fallback route, set the default route fallback
Route::fallback($callback, $plugin = '');
If there is no corresponding route for the URI (including the default route), and no fallback route is set, a 404 response will be returned.
Multiple Route Configuration Files
If you want to manage routes using multiple route configuration files, for example, in the case of multiple applications where each application has its own route configuration, you can load external route configuration files using the require
statement.
For example, in config/route.php
:
<?php
// Load the route configuration for the admin application
require_once app_path('admin/config/route.php');
// Load the route configuration for the api application
require_once app_path('api/config/route.php');