Routing
Default Routing Rules
The default routing rule of 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, visiting:
http://127.0.0.1:8787
will default to calling theindex
method of theapp\controller\IndexController
classhttp://127.0.0.1:8787/foo
will default to calling theindex
method of theapp\controller\FooController
classhttp://127.0.0.1:8787/foo/test
will default to calling thetest
method of theapp\controller\FooController
classhttp://127.0.0.1:8787/admin/foo/test
will default to calling thetest
method of theapp\admin\controller\FooController
class (see Multiple Applications)
Starting from version 1.4, Webman also supports more complex default routing, for example:
app
├── admin
│ └── v1
│ └── v2
│ └── v3
│ └── controller
│ └── IndexController.php
└── controller
├── v1
│ └── IndexController.php
└── v2
└── v3
└── IndexController.php
If you want to change a specific request route, please modify the configuration file config/route.php
.
If you want to disable the default routing, add the following configuration to the last line of the configuration file config/route.php
:
Route::disableDefaultRoute();
Closure Routes
Add the following routing code to config/route.php
:
use support\Request;
Route::any('/test', function (Request $request) {
return response('test');
});
Note
Since closure functions do not belong to any controller,$request->app
,$request->controller
, and$request->action
will all be 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 a/
, for example:
use support\Request;
// Incorrect usage
Route::any('test', function (Request $request) {
return response('test');
});
// Correct usage
Route::any('/test', function (Request $request) {
return response('test');
});
Class Routes
Add the following routing 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 return value 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 matching results will be passed to the corresponding controller method parameters (starting from the second parameter in turn), for example:
// Matches /user/123 and /user/abc
Route::any('/user/{id}', [app\controller\UserController::class, 'get']);
namespace app\controller;
use support\Request;
class UserController
{
public function get(Request $request, $id)
{
return response('Received parameter ' . $id);
}
}
More examples:
use support\Request;
// Matches /user/123, does not match /user/abc
Route::any('/user/{id:\d+}', function (Request $request, $id) {
return response($id);
});
// Matches /user/foobar, does not match /user/foo/bar
Route::any('/user/{name}', function (Request $request, $name) {
return response($name);
});
// Matches /user, /user/123, and /user/abc. [] means optional.
Route::any('/user[/{name}]', function (Request $request, $name = null) {
return response($name ?? 'tom');
});
// Matches any request with /user/ as a prefix.
Route::any('/user/[{path:.+}]', function (Request $request) {
return $request->path();
});
// Matches all options requests. The pattern after the colon specifies the regular expression for this named parameter.
Route::options('[{path:.+}]', function () {
return response('');
});
Summary of advanced usage:
The
[]
syntax in Webman routing is mainly used to handle optional path segments or match dynamic routes. It allows you to define more complex path structures and matching rules for routes.The
:
is used to specify a regular expression.
Route Groups
Sometimes routes contain a large number of identical prefixes, wherein we can use route groups to simplify the definitions. For example:
Route::group('/blog', function () {
Route::any('/create', function (Request $request) {return response('create');});
Route::any('/edit', function (Request $request) {return response('edit');});
Route::any('/view/{id}', function (Request $request, $id) {return response("view $id");});
});
This is equivalent to
Route::any('/blog/create', function (Request $request) {return response('create');});
Route::any('/blog/edit', function (Request $request) {return response('edit');});
Route::any('/blog/view/{id}', function (Request $request, $id) {return response("view $id");});
Nested group usage:
Route::group('/blog', function () {
Route::group('/v1', function () {
Route::any('/create', function (Request $request) {return response('create');});
Route::any('/edit', function (Request $request) {return response('edit');});
Route::any('/view/{id}', function (Request $request, $id) {return response("view $id");});
});
});
Route Middleware
We can set middleware for a specific route or a group of routes. For example:
Route::any('/admin', [app\admin\controller\IndexController::class, '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) {return response("view $id");});
})->middleware([
app\middleware\MiddlewareA::class,
app\middleware\MiddlewareB::class,
]);
# Incorrect usage example (this usage is valid when webman-framework >= 1.5.7)
Route::group('/blog', function () {
Route::group('/v1', function () {
Route::any('/create', function (Request $request) {return response('create');});
Route::any('/edit', function (Request $request) {return response('edit');});
Route::any('/view/{id}', function (Request $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 $request) {return response('create');});
Route::any('/edit', function (Request $request) {return response('edit');});
Route::any('/view/{id}', function (Request $request, $id) {return response("view $id");});
})->middleware([
app\middleware\MiddlewareA::class,
app\middleware\MiddlewareB::class,
]);
});
Resource Routes
Route::resource('/test', app\controller\IndexController::class);
// Specify resource routes
Route::resource('/test', app\controller\IndexController::class, ['index','create']);
// Non-defined resource routes
// For example, accessing notify can be either any route /test/notify or /test/notify/{id}, and routeName is 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, URL generation for nested group routes is not supported.
For example, given 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 will be /blog/100
When using the route's URL in views, this method can be used so that no matter how the routing rules change, the URL will be auto-generated, avoiding a large number of changes to view files due to routing address adjustments.
Getting Route Information
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());
}
Note
If the current request does not match any routes configured inconfig/route.php
, then$request->route
will be null, which means that during default routing,$request->route
will also be null.
Handling 404 Errors
When a route cannot be found, it defaults to returning a 404 status code and outputting 404-related content.
If developers want to intervene in the business process when a route is not found, they can use the fallback route provided by Webman Route::fallback($callback)
method. For example, the following logic redirects to the homepage when a route is not found.
Route::fallback(function(){
return redirect('/');
});
Or when a route does not exist, return a JSON response, which is very useful when Webman is used as an API.
Route::fallback(function(){
return json(['code' => 404, 'msg' => '404 not found']);
});
Adding Middleware to 404
By default, 404 requests do not run any middleware. To add middleware to 404 requests, please refer to the following code.
Route::fallback(function(){
return json(['code' => 404, 'msg' => '404 not found']);
})->middleware([
app\middleware\MiddlewareA::class,
app\middleware\MiddlewareB::class,
]);
Related link Custom 404 500 pages
Disabling Default Routes
// Disable the main project's default routes without affecting application plugins
Route::disableDefaultRoute();
// Disable the routes of the admin application of the main project, without affecting application plugins
Route::disableDefaultRoute('', 'admin');
// Disable the default routes of the foo plugin without affecting the main project
Route::disableDefaultRoute('foo');
// Disable the default routes of the admin application of the foo plugin without affecting the main project
Route::disableDefaultRoute('foo', 'admin');
// Disable the default route for the controller [\app\controller\IndexController::class, 'index']
Route::disableDefaultRoute([\app\controller\IndexController::class, 'index']);
Annotation to Disable Default Routes
We can disable the default routing for a specific controller through annotations, for example:
namespace app\controller;
use support\annotation\DisableDefaultRoute;
#[DisableDefaultRoute]
class IndexController
{
public function index()
{
return 'index';
}
}
Similarly, we can also disable the default routing for a specific method in a controller through annotations, for example:
namespace app\controller;
use support\annotation\DisableDefaultRoute;
class IndexController
{
#[DisableDefaultRoute]
public function index()
{
return 'index';
}
}
Route Interface
// Set the route for any method request for $uri
Route::any($uri, $callback);
// Set the route for get requests for $uri
Route::get($uri, $callback);
// Set the route for post requests for $uri
Route::post($uri, $callback);
// Set the route for put requests for $uri
Route::put($uri, $callback);
// Set the route for patch requests for $uri
Route::patch($uri, $callback);
// Set the route for delete requests for $uri
Route::delete($uri, $callback);
// Set the route for head requests for $uri
Route::head($uri, $callback);
// Set the route for options requests for $uri
Route::options($uri, $callback);
// Simultaneously set routes for multiple types of requests
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 routes
Route::disableDefaultRoute($plugin = '');
// Fallback route, set the default routing fallback
Route::fallback($callback, $plugin = '');
// Get all route information
Route::getRoutes();
If no corresponding route exists for the uri (including the default route), and the fallback route is not set, a 404 will be returned.
Multiple Route Configuration Files
If you want to manage routes with multiple configuration files, for example, when using Multiple Applications where each application has its own route configuration, you can load external route configuration files by requiring them.
For example, in config/route.php
:
<?php
// Load route configurations under the admin application
require_once app_path('admin/config/route.php');
// Load route configurations under the api application
require_once app_path('api/config/route.php');