路由

默认路由规则

webman默认路由规则是 http://127.0.0.1:8787/{控制器}/{动作}

默认控制器为app\controller\Index,默认动作为index

例如访问:

  • http://127.0.0.1:8787 将默认访问app\controller\Index类的index方法
  • http://127.0.0.1:8787/foo 将默认访问app\controller\Foo类的index方法
  • http://127.0.0.1:8787/foo/test 将默认访问app\controller\Foo类的test方法
  • http://127.0.0.1:8787/admin/foo/test 将默认访问app\admin\controller\Foo类的test方法 (参考多应用)

当您想改变某个请求路由时请更改配置文件 config/route.php

如果你想关闭默认路由,在配置文件 config/route.php里最后一行加上如下配置:

  1. Route::disableDefaultRoute();

Route::disableDefaultRoute() 需要workerman/webman-framework 版本>=1.0.13

路由自动解析

当webman-framework < 1.4.0时,webman无法自动解析更复杂的控制器结构,这时可以安装webman的自动路由插件,它会自动检索所有的控制器并为其自动配置对应的路由,让其通过url可以访问。

注意 webman-framework >= 1.4.0 无需安装自动路由插件,路由会自动识别

闭包路由

config/route.php里添加如下路由代码

  1. Route::any('/test', function ($request) {
  2. return response('test');
  3. });

注意 由于闭包函数不属于任何控制器,所以$request->app $request->controller $request->action 全部为空字符串。

当访问地址为 http://127.0.0.1:8787/test 时,将返回test字符串。

注意 路由路径必须以/开头,例如

  1. // 错误的用法
  2. Route::any('test', function ($request) {
  3. return response('test');
  4. });
  5. // 正确的用法
  6. Route::any('/test', function ($request) {
  7. return response('test');
  8. });

类路由

config/route.php里添加如下路由代码

  1. Route::any('/testclass', [app\controller\Index::class, 'test']);

当访问地址为 http://127.0.0.1:8787/testclass 时,将返回app\controller\Index类的test方法的返回值。

路由参数

如果路由中存在参数,通过{key}来匹配,匹配结果将传递到对应的控制器方法参数中(从第二个参数开始依次传递),例如:

  1. // 匹配 /user/123 /user/abc
  2. Route::any('/user/{id}', [app\controller\User::class, 'get']);
  1. namespace app\controller;
  2. class User
  3. {
  4. public function get($request, $id)
  5. {
  6. return response('接收到参数'.$id);
  7. }
  8. }

更多例子:

  1. // 匹配 /user/123, 不匹配 /user/abc
  2. Route::any('/user/{id:\d+}', function ($request, $id) {
  3. return response($id);
  4. });
  5. // 匹配 /user/foobar, 不匹配 /user/foo/bar
  6. Route::any('/user/{name}', function ($request, $name) {
  7. return response($name);
  8. });
  9. // 匹配 /user /user/123 和 /user/abc
  10. Route::any('/user[/{name}]', function ($request, $name = null) {
  11. return response($name ?? 'tom');
  12. });

路由分组

注意 分组路由需要 workerman/webman-framework 版本 >= 1.0.9

有时候路由包含了大量相同的前缀,这时候我们可以用路由分组来简化定义。例如:

  1. Route::group('/blog', function () {
  2. Route::any('/create', function ($rquest) {return response('create');});
  3. Route::any('/edit', function ($rquest) {return response('edit');});
  4. Route::any('/view/{id}', function ($rquest, $id) {return response("view $id");});
  5. });

等价与

  1. Route::any('/blog/create', function ($rquest) {return response('create');});
  2. Route::any('/blog/edit', function ($rquest) {return response('edit');});
  3. Route::any('/blog/view/{id}', function ($rquest, $id) {return response("view $id");});

group嵌套使用

注意 需要 workerman/webman-framework 版本 >= 1.0.12

  1. Route::group('/blog', function () {
  2. Route::group('/v1', function () {
  3. Route::any('/create', function ($rquest) {return response('create');});
  4. Route::any('/edit', function ($rquest) {return response('edit');});
  5. Route::any('/view/{id}', function ($rquest, $id) {return response("view $id");});
  6. });
  7. });

路由中间件

注意 需要 workerman/webman-framework 版本 >= 1.0.12

我们可以给某个一个或某一组路由设置中间件。 例如:

  1. Route::any('/admin', [app\admin\controller\Index::class, 'index'])->middleware([
  2. app\middleware\MiddlewareA::class,
  3. app\middleware\MiddlewareB::class,
  4. ]);
  5. Route::group('/blog', function () {
  6. Route::any('/create', function () {return response('create');});
  7. Route::any('/edit', function () {return response('edit');});
  8. Route::any('/view/{id}', function ($r, $id) {response("view $id");});
  9. })->middleware([
  10. app\middleware\MiddlewareA::class,
  11. app\middleware\MiddlewareB::class,
  12. ]);

注意: ->middleware() 路由中间件作用于 group 分组之后时候,当前路由必须在处于当前分组之下

  1. # 错误使用例子
  2. Route::group('/blog', function () {
  3. Route::group('/v1', function () {
  4. Route::any('/create', function ($rquest) {return response('create');});
  5. Route::any('/edit', function ($rquest) {return response('edit');});
  6. Route::any('/view/{id}', function ($rquest, $id) {return response("view $id");});
  7. });
  8. })->middleware([
  9. app\middleware\MiddlewareA::class,
  10. app\middleware\MiddlewareB::class,
  11. ]);
  1. # 正确使用例子
  2. Route::group('/blog', function () {
  3. Route::group('/v1', function () {
  4. Route::any('/create', function ($rquest) {return response('create');});
  5. Route::any('/edit', function ($rquest) {return response('edit');});
  6. Route::any('/view/{id}', function ($rquest, $id) {return response("view $id");});
  7. })->middleware([
  8. app\middleware\MiddlewareA::class,
  9. app\middleware\MiddlewareB::class,
  10. ]);
  11. });

资源型路由

  1. Route::resource('/test', app\controller\Index::class);
  2. //指定资源路由
  3. Route::resource('/test', app\controller\Index::class, ['index','create']);
  4. //非定义性资源路由
  5. // 如 notify 访问地址则为any型路由 /text/notify或/text/notify/{id} 都可 routeName为 test.notify
  6. Route::resource('/test', app\controller\Index::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生成

注意 需要 workerman/webman-framework 版本 >= 1.0.10
暂时不支持group嵌套的路由生成url

例如路由:

  1. Route::any('/blog/{id}', [app\controller\Blog::class, 'view'])->name('blog.view');

我们可以使用如下方法生成这个路由的url。

  1. route('blog.view', ['id' => 100]); // 结果为 /blog/100

视图里使用路由的url时可以使用此方法,这样不管路由规则如何变化,url都会自动生成,避免因路由地址调整导致大量更改视图文件的情况。

获取路由信息

注意 需要 webman-framework >= 1.3.2

通过$request->route对象我们可以获取当前请求路由信息,例如

  1. $route = $request->route; // 等价与 $route = request()->route;
  2. if ($route) {
  3. var_export($route->getPath());
  4. var_export($route->getMethods());
  5. var_export($route->getName());
  6. var_export($route->getMiddleware());
  7. var_export($route->getCallback());
  8. var_export($route->param()); // 此特性需要 webman-framework >= 1.3.16
  9. }

注意 如果请求没有匹配任何路由(默认路由除外),则$request->route为null

处理404

当路由找不到时默认返回404状态码并输出public/404.html文件内容。

如果开发者想介入路由未找到时的业务流程,可以使用webman提供的回退路由Route::fallback($callback)方法。比如下面的代码逻辑是当路由未找到时重定向到首页。

  1. Route::fallback(function(){
  2. return redirect('/');
  3. });

再比如当路由不存在时返回一个json数据,这在webman作为api接口时非常实用。

  1. Route::fallback(function(){
  2. return json(['code' => 404, 'msg' => '404 not found']);
  3. });

相关连接 自定义404 500页面

路由接口

  1. // 设置$uri的任意方法请求的路由
  2. Route::any($uri, $callback);
  3. // 设置$uri的get请求的路由
  4. Route::get($uri, $callback);
  5. // 设置$uri的请求的路由
  6. Route::post($uri, $callback);
  7. // 设置$uri的put请求的路由
  8. Route::put($uri, $callback);
  9. // 设置$uri的patch请求的路由
  10. Route::patch($uri, $callback);
  11. // 设置$uri的delete请求的路由
  12. Route::delete($uri, $callback);
  13. // 设置$uri的head请求的路由
  14. Route::head($uri, $callback);
  15. // 同时设置多种请求类型的路由
  16. Route::add(['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'], $uri, $callback);
  17. // 分组路由
  18. Route::group($path, $callback);
  19. // 资源路由
  20. Route::resource($path, $callback, [$options]);
  21. // 回退路由,设置默认的路由兜底
  22. Route::fallback($callback);

如果uri没有对应的路由(包括默认路由),且回退路由也未设置,则会返回404。