《PHP實戰:Laravel學習教程之路由模塊》要點:
本文介紹了PHP實戰:Laravel學習教程之路由模塊,希望對您有用。如果有疑問,可以聯系我們。
PHP應用前言
PHP應用本文主要給大家介紹的是關于Laravel路由模塊的相關內容,分享出來供大家參考學習,下面話不多說了,來一起看看詳細的介紹吧.
PHP應用備注:本文是基于Laravel 5.4版本的路由模塊代碼進行分析書寫;
PHP應用模塊組成
PHP應用下圖展示了路由模塊中各個文件的關系,并進行簡要說明;
PHP應用
PHP應用剖析
PHP應用服務提供者
PHP應用看Laravel模塊,首先找ServiceProvider文件,這是模塊與IOC容器交互的入口,從這個文件,可以看出該模塊提供向系統提供了哪些服務;
PHP應用 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(); }
PHP應用路由管理
PHP應用“路由管理”服務有以下元素需要了解:
['uses' => 'FooController@method', 'as' => 'name']
這樣的字符串;對于不同的表現形式,路由在執行時會調用不同的處理;PHP應用注冊流程
PHP應用在項目啟動后,會執行所有ServiceProvider的loadRoutes方法,也就是調用map方法,一般情況下map方法如下
PHP應用 public function map(Router $router){ require __DIR__.'/routes.php'; }
PHP應用這時候,項目就會執行很多Route::get
、Route::post
、Route::group
方法;
PHP應用當遇到Route::group方法時,會實例化一個RouteGroup對象,put進Router管理類的路由組棧頭部;而后當執行get、post這類具體的注冊路由方法時,會把當前路由組棧中所有組的屬性合并進新路由中,將新路由存儲在RouteCollection這個大盒子里;當Route::group的Closure執行完畢時,會把頭部的RouteGroup實例pull出去;
PHP應用當執行Route::resource時,Router管理類會調用ResourceRegister類來完成批量注冊路由;
PHP應用對于 Router::get這類注冊方法,Illuminate\Foudation\helpers提供了簡寫;
Router::get
簡化成 get,Router::post
簡化成 post,Router::put
簡化成 put,Router::patch
簡化成 patch,Router::delete
簡化成 delete,Router::resource
簡化成 resource,PHP應用至此,RouteCollection大盒子就存放了所有要注冊的路由;
PHP應用request 請求匹配流程
PHP應用首先,request請求會經過Foundation/Http/Kernel的handle方法,在這個方法中,請求會執行以下語句
PHP應用 $this->router->dispatch($request)
PHP應用這里的$this->router
,就是Router管理類;dispatch方法如下
PHP應用 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); }
PHP應用1、根據請求找匹配的路由
PHP應用`RouteCollection`根據請求的`http`動作縮小要匹配的路由范圍;在篩選出來的這些路由中依次遍歷,找出第一個符合驗證的路由(需要進行較驗的驗證在`Route`中的`getValidators`方法中聲明);
PHP應用2、將路由綁定到請求上
PHP應用3、觸發RouteMatched事件
PHP應用初始化的`Laravel`項目沒有對`RouteMatched`路由匹配事件進行任何的監聽器綁定,如有需要,可以自定義監聽器,在模塊的`EventServiceProvider`中注冊該事件監聽;這樣一旦請求匹配上某個路由,就可以執行自定義方法了;
PHP應用4、通過 Pipeline 流水線執行路由上綁定的中間件及對應的方法
PHP應用在`runRouteWithinStack`方法中,系統會判斷是否需要執行中間件,如果`IOC`容器中設置了`middleware.disable`的值為`true`,則需要執行的中間件數組為空;否則會找到所有的中間件,并按照`middlewarePriority`對必要的一些中間件進行排序調整;然后執行`$route->run()`
方法;
PHP應用5、根據 request 請求設置 response 的響應頭
PHP應用項目中會用到的一些方法
app('router')->getRoutes()
$request = app('router')->getCurrentRequest()
$route = $request->route() 或 $route = app('router')->getCurrentRoute()
$middlewares = app('router')->gatherRouteMiddleware($route)
PHP應用Url 生成器
PHP應用Url 生成器是什么?
PHP應用舉個例子,
PHP應用 $url = new UrlGenerator( $routes = new RouteCollection, $request = Request::create('http://www.foo.com/') ); $url->to('foo/bar'); // 輸出 http://www.foo.com/foo/bar
PHP應用像這種基于當前請求,生成指定路徑的Url;
PHP應用這部分功能由兩個文件完成,一個是UrlGenerator.php,另一個是RouteUrlGenerator.php;UrlGenerator.php處理根據路徑名生成Url,RouteUrlGenerator.php處理根據路由生成Url;
PHP應用列一些常用的使用:
PHP應用根據路徑名生成
PHP應用使用to方法,第一個參數為路徑,第二個參數是數組,implode后會接著路徑名,第三個參數決定用不用https
PHP應用 // 路徑名是 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)
PHP應用根據路由的 as 名生成
PHP應用使用route方法,第一個參數為指定路由的 as 名,第二個參數是參數數組,第三個參數決定是否顯示根目錄(默認為 true)
PHP應用 $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)
PHP應用 $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']);
PHP應用根據路由的 action 名生成
PHP應用使用action方法,第一個參數為指定路由的 action 名,第二個參數是參數數組,第三個參數決定是否顯示根目錄(默認為 true)
PHP應用 $route = new Route(['GET'], 'foo/bam', ['controller' => 'foo@bar']); $routes->add($route); // 輸出 http://www.foo.com/foo/bam $url->action('foo@bar');
PHP應用 $route = new Route(['GET'], 'foo/invoke', ['controller' => 'InvokableActionStub']); $routes->add($route); // 輸出 http://www.foo.com/foo/invoke $url->action('InvokableActionStub');
PHP應用設置全局默認參數
PHP應用 $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');
PHP應用設置全局命名空間
PHP應用這樣調用的時候,不用在 action 上省略這部分命名空間
PHP應用 // 設置全局命名空間 $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');
PHP應用跳轉器
PHP應用跳轉器內部提供了以下跳轉;
PHP應用home
PHP應用通過調用app('redirect')->home()
會跳轉至根目錄下\;
PHP應用 public function home($status = 302)
PHP應用back
PHP應用通過調用app('redirect')->back()
會跳轉至上一次訪問頁面;或者全局幫助函數back()
也可以;
PHP應用 public function back($status = 302, $headers = [], $fallback = false)
PHP應用第三個參數表示,如果沒有前一次訪問請求,訪問哪個頁面,具體源碼如下:
PHP應用 if ($url) { return $url; } elseif ($fallback) { return $this->to($fallback); } else { return $this->to('/'); }
PHP應用refresh
PHP應用通過調用app('redirect')->refresh()
會刷新當前訪問頁面;
PHP應用 public function refresh($status = 302, $headers = [])
PHP應用to
PHP應用通過調用app('redirect')->to('path')
會跳轉至指定路徑頁面;或者全局幫助函數redirect('path')
也可以;
PHP應用這里的 path 路徑是不包含根目錄的,例如(foo/bar);
PHP應用 public function to($path, $status = 302, $headers = [], $secure = null)
PHP應用第四個參數表示是否使用https;
PHP應用away
PHP應用通過調用app('redirect')->away('path')
會跳轉至指定路徑頁面;
PHP應用這里的 path 路徑是包含根目錄的,例如(http://xx.com/foo/bar);
PHP應用 public function away($path, $status = 302, $headers = [])
PHP應用secure
PHP應用通過調用app('redirect')->secure('path')
會跳轉至指定路徑頁面;這里的path路徑是不包含根目錄的;
PHP應用 public function secure($path, $status = 302, $headers = [])
PHP應用其本質是調用了to方法
PHP應用 return $this->to($path, $status, $headers, true);
PHP應用route
PHP應用通過調用app('redirect')->route('route_as_name')
,根據路由的as名會跳轉至與路由一致的url路徑頁;
PHP應用 public function route($route, $parameters = [], $status = 302, $headers = [])
PHP應用action
PHP應用通過調用app('redirect')->action('route_action')
,根據路由的action名會跳轉至與路由一致的url路徑頁;
PHP應用 public function action($action, $parameters = [], $status = 302, $headers = [])
PHP應用guest
PHP應用跳到指定的路徑頁的同時,將當前url存放至session中,鍵名為url.intended;
PHP應用 public function guest($path, $status = 302, $headers = [], $secure = null)
PHP應用intended
PHP應用跳轉至session中鍵名為url.intended的值所對應的Url;如果不存在,則跳轉至第一個參數所傳的值;
PHP應用 public function intended($default = '/', $status = 302, $headers = [], $secure = null)
PHP應用響應工廠(ResponseFactory)
PHP應用ResponseFactory文件提供了兩部分 API,分別是與響應類型相關和與跳轉相關;
PHP應用響應
PHP應用response()
會返回ResponseFactory實例;
PHP應用視圖響應
PHP應用 response()->view('hello', $data, 200);
PHP應用Jsop響應
PHP應用 response()->json(['name' => 'Abigail', 'state' => 'CA']);
PHP應用Jsonp響應
PHP應用 response()->json(['name' => 'Abigail', 'state' => 'CA'])->withCallback($request->input('callback'));
PHP應用文件響應
PHP應用直接在瀏覽器顯示文件,而不是下載,例如圖片或PDF;file方法第一參數為文件路徑,第二參數選填為頭信息數組;
PHP應用 response()->file($pathToFile, $headers);
PHP應用文件下載
PHP應用download方法第一參數為文件路徑,第二參數選填為文件名,第三參數選填為頭信息數組;
PHP應用 return response()->download($pathToFile, $name, $headers);
PHP應用跳轉
PHP應用這里的跳轉方法,其實調用的還是跳轉器中的方法,不過是在暴露更多的接口,方便調用與使用;
方法名 | 調用 | 實際調用的是跳轉器中的哪個方法 |
---|---|---|
redirectTo | response()->redirectTo(...) | to方法 |
redirectToRoute | response()->redirectToRoute(...) | route方法 |
redirectToAction | response()->redirectToAction(...) | action方法 |
redirectGuest | response()->redirectGuest(...) | guest方法 |
redirectToIntended | response()->redirectToIntended(...) | intended方法 |
PHP應用總結
PHP應用以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持.
轉載請注明本頁網址:
http://www.snjht.com/jiaocheng/279.html