欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Laravel學習教程之路由模塊

 更新時間:2017年08月18日 08:27:01   作者:GreenLightt  
這篇文章主要給大家介紹了Laravel學習教程之路由模塊的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學習或使用laravel具有一定的參考學習價值,需要的朋友們下面跟著小編來一起學習學習吧。

前言

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

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

模塊組成

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


剖析

服務(wù)提供者

看Laravel模塊,首先找ServiceProvider文件,這是模塊與IOC容器交互的入口,從這個文件,可以看出該模塊提供向系統(tǒng)提供了哪些服務(wù);

public function register() {
 // 注冊路由管理,提供路由注冊,路由匹配的功能
 $this->registerRouter();
 // 注冊 Url 生成器實例
 $this->registerUrlGenerator();
 // 注冊跳轉(zhuǎn)器
 $this->registerRedirector();
 // 綁定 PSR-7 請求實現(xiàn)到 ServerRequestInterface 接口
 $this->registerPsrRequest();
 // 綁定 PSR-7 Response 實現(xiàn)到 ResponseInterface 接口
 $this->registerPsrResponse();
 // 注冊 ReponseFactory,提供各式各樣的 Response,比如視圖響應(yīng)、Json響應(yīng)、Jsonp響應(yīng)、文件下載等
 $this->registerResponseFactory();
}

路由管理

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

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

注冊流程

在項目啟動后,會執(zhí)行所有ServiceProvider的loadRoutes方法,也就是調(diào)用map方法,一般情況下map方法如下

public function map(Router $router){
 require __DIR__.'/routes.php';
}

這時候,項目就會執(zhí)行很多Route::get、Route::postRoute::group方法;

當遇到Route::group方法時,會實例化一個RouteGroup對象,put進Router管理類的路由組棧頭部;而后當執(zhí)行g(shù)et、post這類具體的注冊路由方法時,會把當前路由組棧中所有組的屬性合并進新路由中,將新路由存儲在RouteCollection這個大盒子里;當Route::group的Closure執(zhí)行完畢時,會把頭部的RouteGroup實例pull出去;

當執(zhí)行Route::resource時,Router管理類會調(diào)用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請求會經(jīng)過Foundation/Http/Kernel的handle方法,在這個方法中,請求會執(zhí)行以下語句

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

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

public function dispatch(Request $request) {
 $this->currentRequest = $request;
 return $this->dispatchToRoute($request);
}

public function dispatchToRoute(Request $request) {
 // 根據(jù)請求的 url 找到匹配的路由
 $route = $this->findRoute($request);
 // 將路由綁定到請求上
 $request->setRouteResolver(function () use ($route) {
 return $route;
 }
 // 觸發(fā) RouteMatched 事件
 $this->events->dispatch(new Events\RouteMatched($route, $request));
 // 通過 Pipeline 流水線執(zhí)行路由上綁定的中間件及對應(yīng)的方法
 $response = $this->runRouteWithinStack($route, $request);
 // 根據(jù) request 請求設(shè)置 response 的響應(yīng)頭
 return $this->prepareResponse($request, $response);
}

1、根據(jù)請求找匹配的路由

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

2、將路由綁定到請求上

3、觸發(fā)RouteMatched事件

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

4、通過 Pipeline 流水線執(zhí)行路由上綁定的中間件及對應(yīng)的方法

在`runRouteWithinStack`方法中,系統(tǒng)會判斷是否需要執(zhí)行中間件,如果`IOC`容器中設(shè)置了`middleware.disable`的值為`true`,則需要執(zhí)行的中間件數(shù)組為空;否則會找到所有的中間件,并按照`middlewarePriority`對必要的一些中間件進行排序調(diào)整;然后執(zhí)行`$route->run()`方法;

5、根據(jù) request 請求設(shè)置 response 的響應(yīng)頭

項目中會用到的一些方法

  • 獲取路由集合 app('router')->getRoutes()
  • 獲取當前的請求 $request = app('router')->getCurrentRequest()
  • 獲取當前請求所對應(yīng)的路由 $route = $request->route() 或 $route = app('router')->getCurrentRoute()
  • 獲取當前路由需要執(zhí)行的中間件 $middlewares = app('router')->gatherRouteMiddleware($route)

Url 生成器

Url 生成器是什么?

舉個例子,

$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處理根據(jù)路徑名生成Url,RouteUrlGenerator.php處理根據(jù)路由生成Url;

列一些常用的使用:

根據(jù)路徑名生成

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

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

根據(jù)路由的 as 名生成

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

$route = new Route(['GET'], 'foo/bar', ['as' => 'foo']);
$routes->add($route);

// 輸出 'http://www.foo.com/foo/bar
$url->route('foo');

// 第三個參數(shù)為 false,表示不顯示根目錄,于是輸出 /foo/bar
$url->route('foo', [], false)

// 路由中的 url 本身不帶參數(shù),則第二參數(shù)中所有關(guān)聯(lián)數(shù)組都將作為查詢參數(shù)
// 輸出 /foo/bar?foo=bar
$url->route('foo', ['foo' => 'bar'], false)
$route = new Route(['GET'], 'foo/bar/{baz}/breeze/{boom}', ['as' => 'bar']);
$routes->add($route);

// 路由上的 url 帶參數(shù),根據(jù)參數(shù)名找值;剩余多余的為查詢參數(shù);
// 輸出 http://www.foo.com/foo/bar/otwell/breeze/taylor?fly=wall
$url->route('bar', ['boom' => 'taylor', 'baz' => 'otwell', 'fly' => 'wall']);

// 路由上的 url 帶參數(shù),找不到對應(yīng)的參數(shù)值,則按順序作值;剩余多余的為查詢參數(shù);
// 輸出 http://www.foo.com/foo/bar/taylor/breeze/otwell?fly=wall
$url->route('bar', ['taylor', 'otwell', 'fly' => 'wall']);

根據(jù)路由的 action 名生成

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

$route = new Route(['GET'], 'foo/bam', ['controller' => 'foo@bar']);
$routes->add($route);

// 輸出 http://www.foo.com/foo/bam
$url->action('foo@bar');
$route = new Route(['GET'], 'foo/invoke', ['controller' => 'InvokableActionStub']);
$routes->add($route);

// 輸出 http://www.foo.com/foo/invoke
$url->action('InvokableActionStub');

設(shè)置全局默認參數(shù)

$url->defaults(['locale' => 'en']);

$route = new Route(['GET'], 'foo', ['as' => 'defaults', 'domain' => '{locale}.example.com', function() {}]);

// 路由 url 有參數(shù),但沒有傳參數(shù)值,則會找全局默認參數(shù)值;輸出 http://en.example.com/foo
$url->route('defaults');

設(shè)置全局命名空間

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

// 設(shè)置全局命名空間
$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 的最前面加了 `\`,全局命名空間下調(diào)用
$url->action('\something\foo@bar');

跳轉(zhuǎn)器

跳轉(zhuǎn)器內(nèi)部提供了以下跳轉(zhuǎn);

home

通過調(diào)用app('redirect')->home()會跳轉(zhuǎn)至根目錄下\;

public function home($status = 302)

back

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

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

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

if ($url) {
  return $url;
} elseif ($fallback) {
 return $this->to($fallback);
} else {
 return $this->to('/');
}

refresh

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

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

to

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

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

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

第四個參數(shù)表示是否使用https;

away

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

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

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

secure

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

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

其本質(zhì)是調(diào)用了to方法

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

route

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

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

action

通過調(diào)用app('redirect')->action('route_action') ,根據(jù)路由的action名會跳轉(zhuǎn)至與路由一致的url路徑頁;

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

guest

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

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

intended

跳轉(zhuǎn)至session中鍵名為url.intended的值所對應(yīng)的Url;如果不存在,則跳轉(zhuǎn)至第一個參數(shù)所傳的值;

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

響應(yīng)工廠(ResponseFactory)

ResponseFactory文件提供了兩部分 API,分別是與響應(yīng)類型相關(guān)和與跳轉(zhuǎn)相關(guān);

響應(yīng)

response()會返回ResponseFactory實例;

視圖響應(yīng)

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

Jsop響應(yīng)

response()->json(['name' => 'Abigail', 'state' => 'CA']);

Jsonp響應(yīng)

response()->json(['name' => 'Abigail', 'state' => 'CA'])->withCallback($request->input('callback'));

文件響應(yīng)

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

response()->file($pathToFile, $headers);

文件下載

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

return response()->download($pathToFile, $name, $headers);

跳轉(zhuǎn)

這里的跳轉(zhuǎn)方法,其實調(diào)用的還是跳轉(zhuǎn)器中的方法,不過是在暴露更多的接口,方便調(diào)用與使用;

方法名 調(diào)用 實際調(diào)用的是跳轉(zhuǎn)器中的哪個方法
redirectTo response()->redirectTo(...) to方法
redirectToRoute response()->redirectToRoute(...) route方法
redirectToAction response()->redirectToAction(...) action方法
redirectGuest response()->redirectGuest(...) guest方法
redirectToIntended response()->redirectToIntended(...) intended方法

總結(jié)

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

相關(guān)文章

最新評論