laravel5.5學習2-路由系統

1、初識路由

路由系統是全部 PHP 框架的核心,路由承載的是 URL 到代碼片斷的映射,不一樣的框架所附帶的路由系統是這個框架本質最真實的寫照,一絲不掛,盡收眼底。Laravel 路由中文文檔:http://laravel-china.org/docs/5.5/routingphp

Laravel 5.3 以後就把路由放到了 learnlaravel5/routes 文件夾中,一共有四個文件。html

咱們先看一下web.php中僅存的幾行代碼:laravel

Route::get('/', function () {  return view('welcome'); });  Auth::routes();  Route::get('/home', 'HomeController@index')->name('home');

中間的一行代碼 Auth::routes(); 就是 Auth 系統自動注入的路由配置,咱們不用深究,咱們的注意力主要集中頭三行和最後一行代碼上。web

2、命名空間

我一直認爲 Laravel 5 除了性能大幅提高以外相對於 4 最大的進步就在於新的命名空間規劃:更清晰,更合理,更有利於新手。安全

Laravel 4 失敗的簡潔服務器

Laravel 4 時代,大量的代碼都運行在根命名空間下,路由、Controller、Model 等等。看起來這麼作能夠少寫幾行枯燥的 use xxxx;,實則是對於命名空間的誤使用,並且對於新手學習命名空間是有毒的。閉包

絕對類名架構

Laravel 5 全面引入了 psr-4 命名空間標準:命名空間和實際文件所在的文件夾層級一致,文件夾首字母大寫,並自動成爲此文件的約定命名空間。舉個小栗子:learnlaravel5/app/Http/Controllers/HomeController.php 的絕對類名爲:\App\Http\Controllers\HomeControllerlearnlaravel5/app/User.php 的絕對類名爲:\App\User。(實際上 psr-4 是自動加載標準,用在這裏故稱其爲命名空間標準。)app

「絕對類名」是我自創的:在啓用了命名空間的系統中,子命名空間下的類有一個全局均可以直接訪問的名稱,這個名稱就是該類的命名空間全稱。雖然命名空間在「實用主義」的 PHP 語言裏看起來十分古怪,不過他也仍是 PHP 嘛,依然遵循 PHP 的運行原理和哲學。同理,Laravel 不管多麼強大,他都是 PHP 代碼寫成的,因此當你苦於 Laravel 沒有提供某個你須要的功能時,不要驚慌不要着急,just write your PHP code。框架

3、基礎路由解析

一、閉包路由

路由文件中前三行即爲閉包路由:

Route::get('/', function () {  return view('welcome'); });

閉包路由使用閉包做爲此條請求的響應代碼,方便靈活,不少簡單操做直接在閉包裏解決便可。例如「輸出服務器當前時間」:

Route::get('now', function () {  return date("Y-m-d H:i:s"); });

若是你想獲得北京時間,請在 learnlaravel5/config/app.php 第 68 行左右把 timezone 設置爲上海:

'timezone' => 'Asia/Shanghai',

三、控制器@方法 路由

閉包路由雖然靈活強大,不過大多數場景下咱們仍是須要回歸到 MVC 架構的:

Route::get('/home', 'HomeController@index')->name('home');

這行路由代碼的意思想必你們都能猜到一二了:當以 GET 方法訪問 http://fuck.io:1024/home 的時候,調用 HomeController 控制器中的 index 方法(函數)。同理,你可使用 Route::post('/home', 'HomeController@indexPost'); 響應 POST 方法的請求。最後的->name()不是必須的,感興趣能夠本身瞭解。

控制器@方法 調用原理淺析

Laravel 的路由跟全部 PHP 框架的路由同樣,都是用的最簡單直接的 PHP 方式來調用控制器中的方法的:使用字符串初始化類獲得對象,調用對象的指定方法,返回結果。下面我簡單羅列幾步對 Laravel 路由調用過程的探測,感興趣的話能夠本身研究。

learnlaravel5/app/Providers/RouteServiceProvider.php

全局搜索 routes.php,咱們找到了這個文件。此文件最後的 mapWebRoutes 方法,給全部的路由統一加進了一個路由組,定義了一個命名空間和一箇中間件

protected function mapWebRoutes() {  Route::middleware('web')  ->namespace($this->namespace)  ->group(base_path('routes/web.php')); }

順着這個函數往上看,你會發現命名空間定義的地方:

protected $namespace = 'App\Http\Controllers';

以後命名空間、類、方法是如何傳遞的呢?

learnlaravel5/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php

通過簡單的追蹤,咱們找到了這個文件。讓咱們在 dispatch 方法中增長一行 var_dump($controller);,刷新http://127.0.0.1:8000:1024/home就能夠看到頁面上以下的輸出:

開頭的App\Http\Controllers\HomeController就是咱們要調用的控制器類的「絕對類名」,注意這裏是不帶\根命名空間符號的。

4、增長路由組

路由組能夠給組內路由一次性增長 命名空間、uri 前綴、域名限定、中間件 等屬性,而且能夠多級嵌套,異常強大。

如:咱們要使用路由組來將後臺頁面置於「須要登陸才能訪問」的中間件下,以保證安全。在Routes/web.php 裏增長下面三行:

Route::group(['middleware' => 'auth', 'namespace' => 'Admin', 'prefix' => 'admin'], function() {  Route::get('/', 'HomeController@index'); });

命名空間

另外一個常見用例是使用 namespace 方法將相同的 PHP 命名空間分配給路由組的中全部的控制器:

Route::namespace('Admin')->group(function () { // 在 "App\Http\Controllers\Admin" 命名空間下的控制器 });

請記住,默認狀況下,RouteServiceProvider 會在命名空間組中引入你的路由文件,讓你不用指定完整的 App\Http\Controllers 命名空間前綴就能註冊控制器路由。所以,你只須要指定命名空間 App\Http\Controllers 以後的部分。

5、CSRF 保護

指向 web 路由文件中定義的 POSTPUT 或 DELETE 路由的任何 HTML 表單都應該包含一個 CSRF 令牌字段,不然,這個請求將會被拒絕。能夠在 CSRF 文檔 中閱讀有關 CSRF 保護的更多信息:

<form method="POST" action="/profile"> {{ csrf_field() }} ... </form>

6、表單方法僞造

HTML 表單不支持 PUTPATCH 或 DELETE 行爲。因此當你要從 HTML 表單中調用定義了 PUTPATCH 或 DELETE 路由時,你將須要在表單中增長隱藏的 _method 輸入標籤。使用 _method 字段的值做爲 HTTP 的請求方法:

<form action="/foo/bar" method="POST"> <input type="hidden" name="_method" value="PUT"> <input type="hidden" name="_token" value="{{ csrf_token() }}"> </form>

你也可使用輔助函數 method_field 來生成隱藏的 _method 輸入標籤:

{{ method_field('PUT') }}
相關文章
相關標籤/搜索