正文 【Laravel基础】2. 路由模块基础知识 拾年之璐 V管理员 /2021年 /241 阅读 0202 ## 2. 路由模块基础知识 [TOC] ### 2.1 路由的定义方式 路由就是提供接受HTTP请求的路径,并实现与程序交互的功能。 路由的定义文件在根目录routes/web.php 中,初始项目下,可以看到 welcome 页面的定义; ```php Route::get('/', function () { return view('welcome'); }); ``` 关于路由的几种基本的定义方式如下: #### 1. 常规定义 路由上可以定义get、post、put、delete四种基本的请求。如: ```php Route::get('hello', function () { return "Hello LV!"; }); ``` 上述方法执行后,浏览器访问 `localhost/hello` , 即可输入 `Hello LV!`  当然,也可以使用另外两种提交方法:any和match; + any表示不管你是哪种提交方式,我智能的全部接收响应 + match表示接收你指定的提交方式,用数组作为参数传递 示例: ```php Route::any('hello', function () { return "Hello LV!+Any"; }); ``` 示例: ```php Route::match(['get','post'],'hello',function (){ return "Hello LV!+match"; }); ``` 结果:  #### 2. 带动态参数 路径中可以传递参数。 示例: ```php Route::any('hello/{name}', function ($name) { return "Hello ,".$name; }); ``` 结果:  当然该参数可以有很多个。 ### 2.2 控制器的创建方式,以及与路由的绑定 MVC 模式中C 代表控制器,用于接收HTTP 请求,从而进行逻辑处理; 有两种方式可以创建控制器: #### 1. 使用命令创建 使用如下命令,在 `Terminal` 中执行,即可创建一个名为 `TaskController` 的控制器。 ```php php artisan make:controller TaskController ``` 控制器的目录在 `App\Http\Controllers` 目录下。   #### 2. Controllers文件下,使用IDE 直接创建 常规的Controllers文件格式为: ```php where('name','[a-z]+'); Route::get('hello/{name}', 'TaskController@hello2']) ->where('name','[a-z]+'); ``` 如果有多个参数,则也可以进行约束,示例: ```php Route::get('hello/{name}/{id}', [TaskController::class, 'hello2']) ->where(['id'=>'[0-9]+', 'name'=>'[a-z]+']); Route::get('hello/{name}/{id}', 'TaskController@hello2']) ->where(['id'=>'[0-9]+', 'name'=>'[a-z]+']); ``` 如果参数输入不合法,则跳转至404页面。 #### 3. 全局参数约束 上述操作,在某个路由后边进行约束,至对当前路由有效。 如果想对所有的路由有效,则在 `app\Providers\RouteServiceProvider.php` 文件下的 `boot()` 方法中追加以下内容即可: ```php public function boot() { Route::pattern('id', '[0-9]+'); parent::boot(); } ``` 这时,将路由恢复至默认: ```php Route::get('hello/{name}/{id}', [TaskController::class, 'hello2']); Route::get('hello/{name}/{id}', 'TaskController@hello2']); ``` 这里的id,将服从全局约束,限制为数字。 #### 4. 局部解除全局约束 如果想对某一处解除上述全局约束,则将路由写为如下形式: ```php Route::get('hello/{name}/{id}', [TaskController::class, 'hello2']) ->where(['id'=>'.*', 'name'=>'[a-z]+']); Route::get('hello/{name}/{id}', 'TaskController@hello2']) ->where(['id'=>'.*', 'name'=>'[a-z]+']); ``` ### 2.4 路由重定向 可以设置访问一个路由的URI,跳转到另一个路由的URI,具体如下: ``` Route::redirect('index', 'hello'); Route::redirect('index', 'hello', 301); //带状态码 ``` 如果不带状态码,则使用302跳转,即临时跳转 如果带状态码301,则执行301跳转,即永久跳转 还有一个方法,可以直接让路由跳转返回301 状态码而不用设置: ``` Route::permanentRedirect('index', 'task'); ``` ### 2.5 视图路由 在使用视图路由之前,我们先要创建一个视图(MVC)中的V 部分。 视图创建在哪儿呢?在 `resources\views` 目录下。 我们可以在这个目录下新建一个名为 `hello.blade.php` 的文件,然后写入内容: ```html 标题 你好,{{$name}},你的ID是:{{$id}} ``` 然后使用视图,加载该页面。 #### 1. 直接使用视图路由 使用视图路由,有三个参数:1.URI(必);2.名称(必);3.参数(选); 具体方式如下: ```php Route::view('hello', 'hello',['name'=>'张三','id'=>'1001']); ``` 第一个hello对应路由的访问路径,第二个hello对应创建的视图名字。 访问结果:  #### 2. 使用助手函数 示例: ``` Route::get('hello', function () { return view('hello',['name'=>'李四','id'=>'1002']); }); ``` 执行结果:  #### 3. 使用控制器方法(最常用) 这里的路由,使用前面的: ```php Route::get('hello/{name}/{id}', [TaskController::class, 'hello2']); Route::get('hello/{name}/{id}', 'TaskController@hello2']); ``` 然后在控制器中,修改hello2方法,为: ```php public function hello2($name,$id) { return view('hello',['name'=>$name,'id'=>$id]); } ``` 执行结果为:  ### 2.5 路由命名 #### 1. 命名 给一个制定好的路由进行命名,可以生成 URL 地址或进行重定向。如给下面的路由命名为 `hello.hello2`: ```php Route::get('index/direct', [TaskController::class, 'hello']); // 重命名 Route::get('hello', [TaskController::class, 'hello2']) ->name('hello.hello2'); ``` 则可以在控制器的hello方法中,使用助手函数 `route()` 获取路由生成的URL地址: ```php public function hello() { return route('hello.hello2'); } ``` 打印URL结果为:  #### 2. 生成参数URL 也可以打印带参数的URL,如: ``` public function hello() { return route('hello.hello2',['name'=>'zhangsan','id'=>'1001']); } ``` 结果:  如果将前文的路由修改为: ``` Route::get('hello/{name}', [TaskController::class, 'hello2']) ->name('hello.hello2'); ``` 则自动进行参数的匹配:  关于助手函数 `route()` ,默认有3个参数,第3个参数是 是否打印域名。缺省为true,如果设置为false: ``` public function hello() { return route('hello.hello2',['name'=>'zhangsan','id'=>'1001'],false); } ``` 结果为:  #### 3. 重定向跳转 使用redirect()助手结合route()生成一个重定向跳转,注意不要自我死跳。示例: controller: ``` public function hello() { return redirect()->route('hello.hello2',['name'=>'zhangsan','id'=>'1001']); } ``` route: ``` Route::get('hello/{name}/{id}', [TaskController::class, 'hello2']) ->name('hello.hello2'); ``` 执行完成后,跳转至 `http://127.0.0.1:8000/hello/zhangsan/1001` ,如图:  ### 2.6 路由分组 #### 1. 普通的加前缀 使用路由里的 `prefix('前缀名')` 即可实现加前缀。 示例: ``` //这是前面的,不动 Route::get('hello/{name}/{id}', [TaskController::class, 'hello2']) ->name('hello.hello2'); //加前缀 Route::prefix('api')->get('test', function () { return 'test'; }); Route::prefix('api')->get('direct', [TaskController::class, 'hello']); ``` 然后在浏览器中访问,需要加前缀 `api` 才能访问:  #### 2. 使用分组 下面这个例子,是在路由前面加上前缀api ```php Route::group(['prefix' => 'api'], function () { Route::get('index/{id}', function ($id) { return 'index' . $id; }); Route::get('task/{id}', function ($id) { return 'task' . $id; }); }); ``` 当然,我们**推荐**下面这种方式: ```php Route::prefix('api')->group( function () { Route::get('index/{id}', function ($id) { return 'index' . $id; }); Route::get('task/{id}', function ($id) { return 'task' . $id; }); }); ``` #### 3. 使用子域名 也有两种方法,如下: ```php //方式一 Route::domain('127.0.0.1')->group( function () { Route::get('index/{id}', function ($id) { return 'index' . $id; }); Route::get('task/{id}', function ($id) { return 'task' . $id; }); }); //方式二 Route::group(['domain' => '127.0.0.1'], function () { Route::get('index/{id}', function ($id) { return 'index' . $id; }); Route::get('task/{id}', function ($id) { return 'task' . $id; }); }); ``` #### 4. 使用中间件 也有两种方法,如下: ```php //方式一 Route::middleware('中间件名称')->group( function () { Route::get('index/{id}', function ($id) { return 'index' . $id; }); Route::get('task/{id}', function ($id) { return 'task' . $id; }); }); //方式二 Route::group(['middleware' => '中间件名称'], function () { Route::get('index/{id}', function ($id) { return 'index' . $id; }); Route::get('task/{id}', function ($id) { return 'task' . $id; }); }); ``` #### 5. 命名空间 默认的控制类的命名空间是在 `App\Http\Controllers` 目录下。 如果在该目录下新建一个名为 `Admin` 的空间,并在该空间下新建一个名为 `ManageComtroller.php` ,那么路由是无法找到 `Admin` 下的 `ManageComtroller` 控制类的。  那么可以用如下方式访问: ```php Route::namespace('Admin')->group(function () { Route::get('admin/index', [ManageController::class, 'index']); }); ``` 结果:  **但是,在Laravel8中,这些控制类是需要在Route中包含进来的,所以该方式也就没多少用处。** #### 6. 嵌套方式 很少用,不赘述。 如果有用到,再回来补充。 ### 2.7 单行为控制器 顾名思义,定义一个只执行一个方法的控制器。固定使用 `__invoke()` 方法。 可以手动创建,也可以命令创建: ``` php artisan make:controller OneController --invokable ``` 创建完成后,生成一个名为OneController的控制器,默认内容如下: ``` name('localhost.index'); ``` ### 2.10 跳转重定向 重定向使用助手函数redirect(),快捷方式是这样的: ```php Route::get('index', function () { //跳转至首页 return redirect('/'); //return redirect('task'); //跳转到task //return redirect('task/url'); //跳转到task/url }); ``` 当前,快捷方式的完整写法是这样的: ```php Route::get('index', function () { //跳转至首页 return redirect()->to('/'); //跳到首页 //return redirect()->to('task'); //跳转到task //return redirect()->to('task/url'); //跳转到task/url }); ``` 另外,redirect()助手有一个对应的facade 模式对象,也可以使用这种方法: ```php Route::get('index', function () { //跳转至首页 return Redirect::to('/'); //facade 模式,但需要use 引入 }); ``` 另外,使用redirect()的route()方法,可以跳转到指定的命名路由URI: ```php Route::get('one', 'OneController')->name('index.one'); Route::get('index', function () { //跳转至one return redirect()->route('index.one'); }); ``` 使用redirect()的back()方法,可以重定向到上一个页面中: ```php Route::get('back', function () { //后退 return redirect()->back(); //快捷方式 //return back(); }); ``` 使用redirect()的action()方法,可以直接重定向到控制器方法: ```php Route::get('hello2', 'TaskController@hello2'); Route::get('index', function () { //return redirect()->action('TaskController@hello2'); //需注册路由 return redirect()->action('TaskController@hello2', ['name' => 'zhangsan', 'id' => 10]); }); ``` 使用redirect()的away()方法,跳转到外部链接: ```php Route::get('index', function () { return redirect()->away('http://www.baidu.com'); }); ``` 以上。 本文采用创作共用版权 CC BY-NC-SA 3.0 CN 许可协议,转载或复制请注明出处! -- 展开阅读全文 --