基本路由
应用里的大部分的路由都是在 app/Http/routes.php 这个文件里定义的,这个文件会被 App\Providers\RouteServiceProvider 这个类载入进来。最基本的路由就是一个简单的 URI 带一个 Closure:
基本的 GET 路由
Route::get('/', function() { return 'Hello World'; });
当访问应用的根(/)的时候,就会使用上面定义的这个路由,这个路由做的事,就是使用在这个路由里的 Closure,也就是匿名函数,这里就是返回 Hello World 这几个字。
其它的基本路由
Route::post('foo/bar', function() { return 'Hello World'; }); Route::put('foo/bar', function() { // }); Route::delete('foo/bar', function() { // });
Route 的 post 方法定义的是接收 POST 类型的请求的路由,比如当用户把表单提交到 foo/bar 这个地址的时候,就会用上面使用 post 方法定义的那个路由。Route 的 put 方法定义的路由接收 PUT 请求,Route 的 delete 方法定义的路由接收 DELETE 请求。
定义一个有多个动作的路由
Route::match(['get', 'post'], '/', function() { return 'Hello World'; });
上面用 Route 的 match 方法定义的路由,会同时接收 GET 与 POST 类型的请求。
定义可以响应任何 HTTP 动作的路由
Route::any('foo', function() { return 'Hello World'; });
一般你需要为路由生成 URL,可以使用 url 这个帮手去做:
$url = url('foo');
CSRF 保护
Laravel 可以很容易保护应用免受 CSRF(Cross-site request forgeries) 的危险,CSRF 就是跨站请求身份欺诈,也就是已经在你的网站上注册并且登录的用户,在访问一些危险网站的时候,这些网站可能会利用这个用户的身份,对你的网站去执行一些动作。
Laravel 会为每个用户的会话自动生成一个 CSRF “token”,这个 token 可以确定对网站的请求是来自真正的登录的用户,而不是那些危险的网站。
在表单里插入 CSRF Token
<input type="hidden" name="_token" value="<?php echo csrf_token(); ?>">
如果用的是 Blade 模板引擎,应该这样:
<input type="hidden" name="_token" value="{{ csrf_token() }}">
你不需要手工去确认在 POST,PUT,或者 DELETE 请求上的 CSRF token 。VerifyCsrfToken HTTP middleware 会去验证在请求里的 token 是否匹配存储在用户会话里的 token 。
方法欺骗
HTML 的表单并不支持 PUT 还有 DELETE 动作。所以在为表单定义 PUT 或者 DELETE 路由的时候,你需要在表单里用一个隐藏的 _method 字段。这个字段里的值就是使用的 HTTP 请求的方法,比如:
<form action="https://ninghao.net/foo/bar" method="POST"> <input type="hidden" name="_method" value="PUT"> <input type="hidden" name="_token" value="<?php echo csrf_token(); ?>"> </form>
上面的 _method 字段的值是 PUT,这样这个表单在提交的时候,就会使用 PUT 这种 HTTP 的方法。PUT 的意思就是要去修改东西,DELETE 的意思是去删除。
路由参数
你可以获取到请求 URI 里面的某一段东西:
基本的路由参数
Route::get('user/{id}', function($id) { return 'User '.$id; });
{id} 就是地址里的参数,比如用户在用 GET 方法请求 user/1 这个地址的时候,这个 {id} 参数的值就会是 1 ,这个参数的值作为路由里的匿名函数的一个参数传递进来,用 $id 来表示这个参数的值,也就是,如果用户请求 user/1 ,返回的东西就是 User 1 。
可选的路由参数
Route::get('user/{name?}', function($name = null) { return $name; });
{name?},这个参数里用了一个 ? 号,表示这是一个可选的参数。这样用户可以访问 /user 这个地址,也可以访问 /user/wanghao,/user/xiaoxue 这样的地址,如果是这样,这个路由会返回参数的值,也就是 wanghao 或者 xiaoxue 。
带默认值的可选路由参数
Route::get('user/{name?}', function($name = 'John') { return $name; });
$name = 'John' 指定了参数默认的值是 John ,如果访问的地址里不带参数,这个路由就会返回 John 。
用正则表达式约束参数的类型
Route::get('user/{name}', function($name) { // }) ->where('name', '[A-Za-z]+'); Route::get('user/{id}', function($id) { // }) ->where('id', '[0-9]+');
在上面定义的第一个路由里,{name} 这个参数的值的类型必须是字符类型的值,从 A 到 Z ,或者 a 到 z 这样的值。因为这个路由里,用了一个 where 方法,为参数 name 设置了一种匹配的模式,规定了这个参数的值的类型。
第二个路由里 {id} 这个参数的值必须是数字,就是从 0 到 9 这样的数字。如果访问 user/wanghao,会报错,因为参数 {id} 的值是 wanghao,这并不是一个数字类型的值 。
传递一个约束的数组
Route::get('user/{id}/{name}', function($id, $name)
{
//
})
->where(['id' => '[0-9]+', 'name' => '[a-z]+'])
意思是分别限定一下 {id} 参数还有 {name} 参数的值的类型。
定义全局模式
如果你打算用正则表达式在全局范围内去约束路由参数,可以使用 pattern 方法。在 RouteServiceProvider 里的 before 方法上去定义这些模式。
$router->pattern('id', '[0-9]+');
一旦定义了这些模式,会应用在所有的路由参数上:
Route::get('user/{id}', function($id)
{
// {id} 参数必须是数字类型的值
});
访问路由参数里的值
使用 input 方法,可以在路由以外的地方得到路由参数的值:
if ($route->input('id') == 1)
{
//
}
通过 Illuminate\Http\Request 这个实例可以得到当前路由参数。当前请求的请求实例可以通过 Request 这个 facade 得到,或者在依赖注入的地方 type-hinting Illuminate\Http\Request :
use Illuminate\Http\Request;
Route::get('user/{id}', function(Request $request, $id)
{
if ($request->route('id'))
{
//
}
});
命名路由
命名路由就是给路由起个名字,这样可以很方便的生成 URL 或者重定向到一个指定的路由上。使用 as 数组键可以为路由起名字:
Route::get('user/profile', ['as' => 'profile', function()
{
//
}]);
你也需要为控制器动作指定路由的名字:
Route::get('user/profile', [ 'as' => 'profile', 'uses' => 'UserController@showProfile' ]);
现在,你就可以在生成 URL 或者重定向的时候使用路由的名字了:
$url = route('profile'); $redirect = redirect()->route('profile');
currentRouteName 方法可以返回处理当前请求用到的路由的名字:
$name = Route::currentRouteName();
路由群组
有时候你打算在一组群组上使用一个过滤器,不需要为每个路由去指定过滤器,你可以使用路由群组:
Route::group(['middleware' => 'auth'], function() { Route::get('/', function() { // 应用了 Auth 过滤器 }); Route::get('user/profile', function() { // 应用了 Auth 过滤器 }); });
你可以在 group 数组上使用 namespace 参数来指定命名空间:
Route::group(['namespace' => 'Admin'], function()
{
//
});
注意:默认情况下,在你的 routes.php 文件里的 RouteServiceProvider 会带一个命名空间的群组,允许你在注册控制器路由的时候,不需要指定全部的命名空间。
子域名路由
Laravel 可以处理 wildcard 子域名,会传递来自域名的 wildcard 参数。
定义子域名路由
Route::group(['domain' => '{account}.myapp.com'], function()
{
Route::get('user/{id}', function($account, $id)
{
//
});
});
路由前缀
使用在 group 里的属性数组的 prefix 选项,可以为一个路由群组设置一个前缀。
Route::group(['prefix' => 'admin'], function()
{
Route::get('user', function()
{
//
});
});
路由模型绑定
路由模型绑定提供了一种方便的方法,可以把类的实例注入到路由里面。比如你不需要只注入用户的 ID ,你可以注入整个 User 类的实例匹配给定的 ID 。
首先,使用路由的 model 方法,为给定的参数指定类(class)。你需要在 RouteServiceProvider::boot 方法上去定义模型绑定:
把一个参数绑定到一个模型上
public function boot(Router $router) { parent::boot($router); $router->model('user', 'App\User'); }
然后,去定义一个包含 {user} 参数的路由:
Route::get('profile/{user}', function(App\User $user)
{
//
});
把 {user} 参数绑定到了 App\User 模型以后,这样一个 User 实例就会被注入到路由里面。比如,请求的是 profile/1 ,就将会注入一个 ID 号是 1 的 User 的实例。
注意:如果在数据库里没找到匹配的模型实例,会扔出一个 404 的错误。
如果你想指定自己的 “ not found” ,可以传递一个 Closure 作为 model 方法的第三个参数:
Route::model('user', 'User', function() { throw new NotFoundHttpException; });
如果你想使用自己的 resolution 逻辑,可以使用 Router::bind 方法。传递给 bind 方法的 Closure 会接收到 URL 片段上的值,你要返回一个要注入到路由里的类的实例:
Route::bind('user', function($value) { return User::where('name', $value)->first(); });
抛出 404 错误
有两种在路由上触发 404 错误的方法。第一种是可以使用 abort 帮手:
abort(404);
abort 帮手只会简单的抛出一个带特定状态码的 Symfony\Component\HttpFoundation\Exception\HttpException 。
第二种方法是可以手工抛出一个 Symfony\Component\HttpKernel\Exception\NotFoundHttpException. 的实例。
Laravel Laravel5 中文手册
评论
就是存放地址变了,其他倒是和4没啥差别
9 年 9 个月 以前
不对,少说了,5多了个controllers
Route::controllers([
'auth' => 'Auth\AuthController',
'password' => 'Auth\PasswordController',
]);
9 年 9 个月 以前
浩哥:
laravel 路由 post 提交问题
TokenMismatchException in VerifyCsrfToken.php line 53:
用postman get 提交的就好使
用postman post 提交的就报错,期间也做了一个模拟的 表单 还是没效果
请问这是什么原因造成的。
9 年 2 个月 以前