一.基本路由
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 IlluminateRoutingRouter $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中的定义的控制器位于AppHttpControllers命名空间下,所以如果要指定命名空间,只需指定AppHttpControllers之后的部分即可
Route::group(['namespace' => 'Admin'], function(){ // 控制器在 "AppHttpControllersAdmin" 命名空间下 Route::group(['namespace' => 'User'], function(){ // 控制器在 "AppHttpControllersAdminUser" 命名空间下 }); });
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', 'AppModelsUser'); parent::boot($router); } 接下来,定义一个包含{user} 参数的路由到控制器中 Route::get('/{user}', 'MyContorller@index'); MyContorller中 public function index(User $user) { dd($user); } 也可以使用路由的闭包 $router->get('/{user}', function(AppModelsUser $user) { // });
如果在匹配模型实例的时候在数据库中找不到对应记录,那么就会自动抛出404异常.
如果你想要指定自己的“not found”行为,可以传递一个闭包作为第三个参数到model 方法:
public function boot(Router $router) { $router->model('user', 'AppModelsUser', 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.手动抛出SymfonyComponentHttpKernelExceptionNotFoundHttpException的实例
如
throw new NotFoundHttpException;