一.基本路由
1.Route::get('/', function () { return 'Hello World'; }); 2.Route::post('foo/bar', function () { return 'Hello World'; }); 3.Route::put('foo/bar', function () { // }); 4.Route::delete('foo/bar', function () { // }); 5.為多個動作注冊路由 Route::match(['get', 'post'], '/', function () { return 'Hello World'; }); 或者使用any方法注冊一個路由來相應所有HTTP動作 Route::any('foo', function () { return 'Hello World'; }); 6.生成路由對應的urls $url = url('foo');
二.路由參數
1.基本
Route::get('user/{id}', function ($id) { return 'User '.$id; }); 這將匹配url為user/**** 匹配多個 Route::get('posts/{post}/comments/{comment}', function ($postId, $commentId) { // }); 路由參數總是通過花括號進行包裹,參數在路由被執行時會被傳遞到路由的閉包。 注意:路由參數不能包含’- ‘字符,需要的話可以使用_替代。
2.可選參數
如果參數是可選的,即出現不出現都行,在參數后加個? Route::get('user/{name?}', function ($name = null) { return $name; }); Route::get('user/{name?}', function ($name = 'John') { return $name; });
3.正則約束
可以使用路由實例上的where 方法來約束路由參數的格式。where 方法接收參數名和一個正則表達式來定義該參數如何被約束
Route::get('user/{name}', function ($name) { //匹配/user/后面跟字符串,如果匹配不到,返回404錯誤 })->where('name', '[A-Za-z]+'); Route::get('user/{id}', function ($id) { // })->where('id', '[0-9]+'); Route::get('user/{id}/{name}', function ($id, $name) { // })->where(['id' => '[0-9]+', 'name' => '[a-z]+']);
4.全局約束
路由參數在全局范圍內被給定正則表達式約束,可以使用pattern 方法。可以在RouteServiceProvider 類的boot 方法中定義約束模式
/** * 定義路由模型綁定,模式過濾器等 * * @param \Illuminate\Routing\Router $router * @return void * @translator http://laravelacademy.org */ public function boot(Router $router){ $router->pattern('id', '[0-9]+'); parent::boot($router); }
三.命名路由
關鍵字as
1.命名路由
命名路由使生成 URLs 或者重定向到指定路由變得很方便,在定義路由時指定路由名稱,然后使用數組鍵as 指定路由別名
Route::get('user/profile', ['as' => 'profile', function () { // }]); 還可以為控制器動作指定路由名稱 Route::get('user/profile', [ 'as' => 'profile', 'uses' => 'UserController@showProfile' ]);
命名路由僅為路由名稱在應用內傳遞獲取更加方便,對外是不能提供訪問的.如你不能通過profile來訪問user/profile;可以通過route取出實際地址
2.為命名路由生成 URLs
$url = route('profile'); $redirect = redirect()->route('profile'); 路由定義了參數,可以將路由參數作為第二個參數傳遞給route 函數 Route::get('user/{id}/profile', ['as' => 'profile', function ($id) { // }]); $url = route('profile', ['id' => 1]);
四.路由分組
關鍵詞group
1.路由中指定中間件
Route::group(['middleware' => 'auth'], function () { Route::get('/', function () { // 使用 Auth 中間件 }); Route::get('user/profile', function () { // 使用 Auth 中間件 }); });
2.命名空間(適用於控制器)
默認情況下,routes.php中的定義的控制器位於App\Http\Controllers命名空間下,所以如果要指定命名空間,只需指定App\Http\Controllers之后的部分即可
Route::group(['namespace' => 'Admin'], function(){ // 控制器在 "App\Http\Controllers\Admin" 命名空間下 Route::group(['namespace' => 'User'], function(){ // 控制器在 "App\Http\Controllers\Admin\User" 命名空間下 }); });
3.子域名路由
Route::group(['domain' => '{account}.myapp.com'], function () { Route::get('user/{id}', function ($account, $id) { // }); });
4.路由前綴
Route::group(['prefix' => 'admin'], function () { Route::get('users', function () { // 匹配 "/admin/users" URL }); }); 還可以使用prefix 參數為分組路由指定公共參數: Route::group(['prefix' => 'accounts/{account_id}'], function () { Route::get('detail', function ($account_id) { // 匹配 accounts/{account_id}/detail URL }); });
五.防止CSRF攻擊
1.在模板中添加csrf字段
{!! csrf_field() !!}
2.從CSRF中排除URIs
在VerifyCsrfToken 中間件中將要排除的 URIs 添加到$except 屬性
class VerifyCsrfToken extends BaseVerifier { /** *從 CSRF 驗證中排除的 URL * * @var array */ protected $except = [ 'stripe/*', ]; }
3.X-CSRF-Token
除了將 CSRF 令牌作為一個 POST 參數進行檢查,Laravel 的VerifyCsrfToken 中間件還會檢查X-CSRF-TOKEN請求頭,你可以將令牌保存在”meta”標簽中:
<meta name="csrf-token" content="{{ csrf_token() }}">
創建完這個 meta 標簽后,就可以在 js 庫如 jQuery 中添加該令牌到所有請求頭,這為基於 AJAX 的應用提供了簡單、方便的方式來避免 CSRF 攻擊:
$.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') } });
4.X-XSRF-Token
Laravel 還將 CSRF 令牌保存到了名為XSRF-TOKEN 的 cookie 中,你可以使用該 cookie 值來設置X-XSRF-TOKEN 請求頭。一些 JavaScript 框架,比如 Angular,將會為你自動進行設置,基本上你不太會手動設置這個值。
六.路由模型綁定
1.Laravel 路由模型綁定為注入類實例到路由提供了方便,例如,你可以將匹配給定 ID 的整個User 類實例注入到路由中,而不是直接注入用戶 ID.首先,使用路由的model 方法為給定參數指定一個類,你應該在RouteServiceProvider::boot 方法中定義模型綁定:
綁定參數到模型 public function boot(Router $router) { $router->model('user', 'App\Models\User'); parent::boot($router); } 接下來,定義一個包含{user} 參數的路由到控制器中 Route::get('/{user}', 'MyContorller@index'); MyContorller中 public function index(User $user) { dd($user); } 也可以使用路由的閉包 $router->get('/{user}', function(App\Models\User $user) { // });
如果在匹配模型實例的時候在數據庫中找不到對應記錄,那么就會自動拋出404異常.
如果你想要指定自己的“not found”行為,可以傳遞一個閉包作為第三個參數到model 方法:
public function boot(Router $router) { $router->model('user', 'App\Models\User', function() { throw new NotFoundHttpException; }); parent::boot($router); } 有時候你需要自定義的模型綁定,比如你不想綁定id,而是想綁定name,則在RouteServiceProvider應該使用bind方法 public function boot(Router $router) { $router->bind('user', function ($value) { return User::where('name', $value)->first();//找不到數據依然會返回 return User::where('name', $value)->firstOrFail(); // 找不到數據返回默認的404 }); }
七.表單方法偽造
HTML 表單不支持PUT 、PATCH 或者DELETE 動作,因此,當定義被 HTML 表單調用的PUT 、PATCH 或DELETE 路由時,需要添加一個隱藏的_method 字段到給表單中,其值被用作 HTTP 請求方法名:
<form action="/foo/bar" method="POST"> <input type="hidden" name="_method" value="PUT"> <input type="hidden" name="_token" value="{{ csrf_token() }}"> </form>
八.拋出404錯誤
1.使用abort
abort(404);
2.手動拋出Symfony\Component\HttpKernel\Exception\NotFoundHttpException的實例
如
throw new NotFoundHttpException;