首页 > 代码库 > Laravel之路由

Laravel之路由

一.基本路由

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

 

 

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=http://www.mamicode.com/"PUT">
<input type="hidden" name="_token" value=http://www.mamicode.com/"{{ csrf_token() }}">
</form>

 

 

八.抛出404错误

1.使用abort

abort(404);

  

2.手动抛出Symfony\Component\HttpKernel\Exception\NotFoundHttpException的实例

throw new NotFoundHttpException;

 

Laravel之路由