一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - PHP教程 - Laravel學習教程之路由模塊

Laravel學習教程之路由模塊

2021-06-19 21:25GreenLightt PHP教程

這篇文章主要給大家介紹了Laravel學習教程之路由模塊的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或使用laravel具有一定的參考學習價值,需要的朋友們下面跟著小編來一起學習學習吧。

前言

本文主要給大家介紹的是關于laravel路由模塊的相關內容,分享出來供大家參考學習,下面話不多說了,來一起看看詳細的介紹吧。

備注:本文是基于laravel 5.4版本的路由模塊代碼進行分析書寫;

模塊組成

下圖展示了路由模塊中各個文件的關系,并進行簡要說明;

Laravel學習教程之路由模塊

剖析

服務提供者

看laravel模塊,首先找serviceprovider文件,這是模塊與ioc容器交互的入口,從這個文件,可以看出該模塊提供向系統提供了哪些服務;

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public function register() {
 // 注冊路由管理,提供路由注冊,路由匹配的功能
 $this->registerrouter();
 // 注冊 url 生成器實例
 $this->registerurlgenerator();
 // 注冊跳轉器
 $this->registerredirector();
 // 綁定 psr-7 請求實現到 serverrequestinterface 接口
 $this->registerpsrrequest();
 // 綁定 psr-7 response 實現到 responseinterface 接口
 $this->registerpsrresponse();
 // 注冊 reponsefactory,提供各式各樣的 response,比如視圖響應、json響應、jsonp響應、文件下載等
 $this->registerresponsefactory();
}

路由管理

“路由管理”服務有以下元素需要了解:

  • route:路由;會記錄 url、http 動作、action (路由要執行的具體對象,可能是 closure,也可以是某個 controller 中的方法),路由參數,路由參數的約束;
  • routecollection:路由集,用來存儲所有route對象的“盒子”;
  • routegroup:路由組;只有路由注冊過程中會臨時用到;存儲一批路由公共的一些屬性,屬性包括domain、prefix、as、middleware、namespace、where;
  • resource:資源路由;資源路由是一套路由的統稱,包含列表(index)、顯示增加(create)、保存增加(store)、顯示詳情(show)、顯示編輯詳情(edit)、更新編輯(update)、刪除詳情(destory);同時可以通過調用only或except方法或參數的形式只生成部分路由;
  • action:路由要執行的對象;有兩種表現形式,一是closure函數,二是類似['uses' => 'foocontroller@method', 'as' => 'name']這樣的字符串;對于不同的表現形式,路由在執行時會調用不同的處理;

注冊流程

在項目啟動后,會執行所有serviceprovider的loadroutes方法,也就是調用map方法,一般情況下map方法如下

?
1
2
3
public function map(router $router){
 require __dir__.'/routes.php';
}

這時候,項目就會執行很多route::getroute::postroute::group方法;

當遇到route::group方法時,會實例化一個routegroup對象,put進router管理類的路由組棧頭部;而后當執行get、post這類具體的注冊路由方法時,會把當前路由組棧中所有組的屬性合并進新路由中,將新路由存儲在routecollection這個大盒子里;當route::group的closure執行完畢時,會把頭部的routegroup實例pull出去;

當執行route::resource時,router管理類會調用resourceregister類來完成批量注冊路由;

對于 router::get這類注冊方法,illuminate\foudation\helpers提供了簡寫;

  • router::get 簡化成 get,
  • router::post 簡化成 post,
  • router::put 簡化成 put,
  • router::patch 簡化成 patch,
  • router::delete 簡化成 delete,
  • router::resource簡化成 resource,

至此,routecollection大盒子就存放了所有要注冊的路由;

request 請求匹配流程

首先,request請求會經過foundation/http/kernel的handle方法,在這個方法中,請求會執行以下語句

?
1
$this->router->dispatch($request)

這里的$this->router,就是router管理類;dispatch方法如下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public function dispatch(request $request) {
 $this->currentrequest = $request;
 return $this->dispatchtoroute($request);
}
 
public function dispatchtoroute(request $request) {
 // 根據請求的 url 找到匹配的路由
 $route = $this->findroute($request);
 // 將路由綁定到請求上
 $request->setrouteresolver(function () use ($route) {
 return $route;
 }
 // 觸發 routematched 事件
 $this->events->dispatch(new events\routematched($route, $request));
 // 通過 pipeline 流水線執行路由上綁定的中間件及對應的方法
 $response = $this->runroutewithinstack($route, $request);
 // 根據 request 請求設置 response 的響應頭
 return $this->prepareresponse($request, $response);
}

1、根據請求找匹配的路由

`routecollection`根據請求的`http`動作縮小要匹配的路由范圍;在篩選出來的這些路由中依次遍歷,找出第一個符合驗證的路由(需要進行較驗的驗證在`route`中的`getvalidators`方法中聲明);

2、將路由綁定到請求上

3、觸發routematched事件

初始化的`laravel`項目沒有對`routematched`路由匹配事件進行任何的監聽器綁定,如有需要,可以自定義監聽器,在模塊的`eventserviceprovider`中注冊該事件監聽;這樣一旦請求匹配上某個路由,就可以執行自定義方法了;

4、通過 pipeline 流水線執行路由上綁定的中間件及對應的方法

在`runroutewithinstack`方法中,系統會判斷是否需要執行中間件,如果`ioc`容器中設置了`middleware.disable`的值為`true`,則需要執行的中間件數組為空;否則會找到所有的中間件,并按照`middlewarepriority`對必要的一些中間件進行排序調整;然后執行`$route->run()`方法;

5、根據 request 請求設置 response 的響應頭

項目中會用到的一些方法

  • 獲取路由集合 app('router')->getroutes()
  • 獲取當前的請求 $request = app('router')->getcurrentrequest()
  • 獲取當前請求所對應的路由 $route = $request->route() 或 $route = app('router')->getcurrentroute()
  • 獲取當前路由需要執行的中間件 $middlewares = app('router')->gatherroutemiddleware($route)

url 生成器

url 生成器是什么?

舉個例子,

?
1
2
3
4
5
6
$url = new urlgenerator(
 $routes = new routecollection,
 $request = request::create('http://www.foo.com/')
);
 
$url->to('foo/bar'); // 輸出 http://www.foo.com/foo/bar

像這種基于當前請求,生成指定路徑的url;

這部分功能由兩個文件完成,一個是urlgenerator.php,另一個是routeurlgenerator.php;urlgenerator.php處理根據路徑名生成url,routeurlgenerator.php處理根據路由生成url;

列一些常用的使用:

根據路徑名生成

使用to方法,第一個參數為路徑,第二個參數是數組,implode后會接著路徑名,第三個參數決定用不用https

?
1
2
3
4
5
6
7
8
9
// 路徑名是 foo/bar,當前請求的根路徑為 http://www.foo.com,所以輸出是 http://www.foo.com/foo/bar
$url->to('foo/bar')
// 路徑名是 foo/bar,當前請求的根路徑為 http://www.foo.com,第三個參數決定 scheme 是 https,所以輸出是 https://www.foo.com/foo/bar
$url->to('foo/bar', [], true)
// 路徑名是 foo/bar,第二個參數 是補充路徑名,implode 后是 /baz/boom
// 第三個參數決定 scheme 是 https,所以輸出是 https://www.foo.com/foo/bar/baz/boom
$url->to('foo/bar', ['baz', 'boom'], true)
// 路徑名是 foo/bar,查詢參數是 ?foo=bar ,補充路徑是 /baz,所以輸出是 https://www.foo.com/foo/bar/baz?foo=bar
$url->to('foo/bar?foo=bar', ['baz'], true)

根據路由的 as 名生成

使用route方法,第一個參數為指定路由的 as 名,第二個參數是參數數組,第三個參數決定是否顯示根目錄(默認為 true)

?
1
2
3
4
5
6
7
8
9
10
11
12
$route = new route(['get'], 'foo/bar', ['as' => 'foo']);
$routes->add($route);
 
// 輸出 'http://www.foo.com/foo/bar
$url->route('foo');
 
// 第三個參數為 false,表示不顯示根目錄,于是輸出 /foo/bar
$url->route('foo', [], false)
 
// 路由中的 url 本身不帶參數,則第二參數中所有關聯數組都將作為查詢參數
// 輸出 /foo/bar?foo=bar
$url->route('foo', ['foo' => 'bar'], false)
?
1
2
3
4
5
6
7
8
9
10
$route = new route(['get'], 'foo/bar/{baz}/breeze/{boom}', ['as' => 'bar']);
$routes->add($route);
 
// 路由上的 url 帶參數,根據參數名找值;剩余多余的為查詢參數;
// 輸出 http://www.foo.com/foo/bar/otwell/breeze/taylor?fly=wall
$url->route('bar', ['boom' => 'taylor', 'baz' => 'otwell', 'fly' => 'wall']);
 
// 路由上的 url 帶參數,找不到對應的參數值,則按順序作值;剩余多余的為查詢參數;
// 輸出 http://www.foo.com/foo/bar/taylor/breeze/otwell?fly=wall
$url->route('bar', ['taylor', 'otwell', 'fly' => 'wall']);

根據路由的 action 名生成

使用action方法,第一個參數為指定路由的 action 名,第二個參數是參數數組,第三個參數決定是否顯示根目錄(默認為 true)

?
1
2
3
4
5
$route = new route(['get'], 'foo/bam', ['controller' => 'foo@bar']);
$routes->add($route);
 
// 輸出 http://www.foo.com/foo/bam
$url->action('foo@bar');
?
1
2
3
4
5
$route = new route(['get'], 'foo/invoke', ['controller' => 'invokableactionstub']);
$routes->add($route);
 
// 輸出 http://www.foo.com/foo/invoke
$url->action('invokableactionstub');

設置全局默認參數

?
1
2
3
4
5
6
$url->defaults(['locale' => 'en']);
 
$route = new route(['get'], 'foo', ['as' => 'defaults', 'domain' => '{locale}.example.com', function() {}]);
 
// 路由 url 有參數,但沒有傳參數值,則會找全局默認參數值;輸出 http://en.example.com/foo
$url->route('defaults');

設置全局命名空間

這樣調用的時候,不用在 action 上省略這部分命名空間

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 設置全局命名空間
$url->setrootcontrollernamespace('namespace');
 
// 配置添加路由
$route = new route(['get'], 'foo/bar', ['controller' => 'namespace\foo@bar']);
$routes->add($route);
$route = new route(['get'], 'foo/invoke', ['controller' => 'namespace\invokableactionstub']);
$routes->add($route);
 
// 輸出 http://www.foo.com/foo/bar; action 的值省略 namespace 這個命名空間
$url->action('foo@bar');
// 輸出 http://www.foo.com/foo/invoke; action 的值省略 namespace 這個命名空間
$url->action('invokableactionstub');
 
// 配置添加路由
$route = new route(['get'], 'something/else', ['controller' => 'something\foo@bar']);
$routes->add($route);
 
// 輸出 http://www.foo.com/something/else; action 的最前面加了 `\`,全局命名空間下調用
$url->action('\something\foo@bar');

跳轉器

跳轉器內部提供了以下跳轉;

home

通過調用app('redirect')->home()會跳轉至根目錄下\;

?
1
public function home($status = 302)

back

通過調用app('redirect')->back()會跳轉至上一次訪問頁面;或者全局幫助函數back()也可以;

?
1
public function back($status = 302, $headers = [], $fallback = false)

第三個參數表示,如果沒有前一次訪問請求,訪問哪個頁面,具體源碼如下:

?
1
2
3
4
5
6
7
if ($url) {
  return $url;
} elseif ($fallback) {
 return $this->to($fallback);
} else {
 return $this->to('/');
}

refresh

通過調用app('redirect')->refresh()會刷新當前訪問頁面;

?
1
public function refresh($status = 302, $headers = [])

to

通過調用app('redirect')->to('path')會跳轉至指定路徑頁面;或者全局幫助函數redirect('path')也可以;

這里的 path 路徑是不包含根目錄的,例如(foo/bar);

?
1
public function to($path, $status = 302, $headers = [], $secure = null)

第四個參數表示是否使用https;

away

通過調用app('redirect')->away('path')會跳轉至指定路徑頁面;

這里的 path 路徑是包含根目錄的,例如(http://xx.com/foo/bar);

?
1
public function away($path, $status = 302, $headers = [])

secure

通過調用app('redirect')->secure('path')會跳轉至指定路徑頁面;這里的path路徑是不包含根目錄的;

?
1
public function secure($path, $status = 302, $headers = [])

其本質是調用了to方法

?
1
return $this->to($path, $status, $headers, true);

route

通過調用app('redirect')->route('route_as_name') ,根據路由的as名會跳轉至與路由一致的url路徑頁;

?
1
public function route($route, $parameters = [], $status = 302, $headers = [])

action

通過調用app('redirect')->action('route_action') ,根據路由的action名會跳轉至與路由一致的url路徑頁;

?
1
public function action($action, $parameters = [], $status = 302, $headers = [])

guest

跳到指定的路徑頁的同時,將當前url存放至session中,鍵名為url.intended;

?
1
public function guest($path, $status = 302, $headers = [], $secure = null)

intended

跳轉至session中鍵名為url.intended的值所對應的url;如果不存在,則跳轉至第一個參數所傳的值;

?
1
public function intended($default = '/', $status = 302, $headers = [], $secure = null)

響應工廠(responsefactory)

responsefactory文件提供了兩部分 api,分別是與響應類型相關和與跳轉相關;

響應

response()會返回responsefactory實例;

視圖響應

?
1
response()->view('hello', $data, 200);

jsop響應

?
1
response()->json(['name' => 'abigail', 'state' => 'ca']);

jsonp響應

?
1
response()->json(['name' => 'abigail', 'state' => 'ca'])->withcallback($request->input('callback'));

文件響應

直接在瀏覽器顯示文件,而不是下載,例如圖片或pdf;file方法第一參數為文件路徑,第二參數選填為頭信息數組;

?
1
response()->file($pathtofile, $headers);

文件下載

download方法第一參數為文件路徑,第二參數選填為文件名,第三參數選填為頭信息數組;

?
1
return response()->download($pathtofile, $name, $headers);

跳轉

這里的跳轉方法,其實調用的還是跳轉器中的方法,不過是在暴露更多的接口,方便調用與使用;

 

方法名 調用 實際調用的是跳轉器中的哪個方法
redirectto response()->redirectto(...) to方法
redirecttoroute response()->redirecttoroute(...) route方法
redirecttoaction response()->redirecttoaction(...) action方法
redirectguest response()->redirectguest(...) guest方法
redirecttointended response()->redirecttointended(...) intended方法

 

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。

原文鏈接:https://segmentfault.com/a/1190000010440480

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 欧美一卡二卡科技有限公司 | 国产日韩欧美不卡www | 17岁俄罗斯csgo | 国产精品久久久久久久久齐齐 | 色哟哟在线视频 | 欧美高清在线精品一区 | 女黑人尺寸bbb | 精品国产一区二区三区久久影院 | 精品久久久久香蕉网 | 日韩视频免费看 | 久久精品国产免费 | 丰腴尤物贵妇浪荡小说 | 日本福利片国产午夜久久 | 国产精品女主播大秀在线 | 午夜福利院电影 | 国产精品亚洲专区在线播放 | 久久xxxx| 日韩国产成人精品视频 | 羞羞色男人的天堂伊人久久 | 91桃色视频 | 污樱桃视频 | 国产一区二区三区高清 | 99精品网 | 亚洲 欧美 国产 视频二区 | 午夜欧美精品久久久久久久久 | 小草观看免费高清视频 | 国产精品永久免费自在线观看 | xxxx在线视频 | 久久婷婷电影网 | 日本不卡不码高清免费观看 | 免费国产在线视频 | 亚洲gogo人体大胆西西安徽 | 国产福利在线观看91精品 | 60岁妇女毛片免费观看 | 亚洲高清影院 | 日韩精品一区二区三区视频 | 亚洲欧美日韩另类在线 | 欧美一区二区三区视视频 | free极度另类性欧美 | 精品视频在线免费播放 | 青青青青久久国产片免费精品 |