1 路由机制
MVC中路由是一个非常重要的功能,其作用是:
A.根据用户访问(URL)匹配传入的请求及请求附带的参数;
B.调用请求映射Controller的Action方法,并把参数传入;
C.返回Action方法处理结果;
下图以简单的形式表示一个用户请求:
2 Laravel中的路由
在Laravel 5.1.4中,路由配置文件是 app/Http/routes.php。
2.1 直接返回字符串的路由
在原有的代码后面追加如下代码段:
Route::get('/hw', function () {
return 'Hello World';
});
打开浏览器访问:http://localhost:801/hw,如下图示:
当然,除了定义get路由以外,还可以定义post、put和delete路由:
Route::post('/hw', function()
{
//
});
Route::put('/hw', function()
{
//
});
Route::delete('/hw', function()
{
//
});
我们也可以同时定义多种请求的路由:
Route::match(['get', 'post'], '/hw', function()
{
return 'Hello World';
});
又或者注册一个响应所有类型请求的路由:
Route::any('/hw', function()
{
return 'Hello World';
});
由于HTML表单并没有put和delete请求,我们可以模拟这两种方式:
<form action="/hw" method="POST">
<input type="hidden" name="_method" value="PUT">
<input type="hidden" name="_token" value="<?php echo csrf_token(); ?>">
</form>
2.2 返回视图的路由
在上面的代码中再追加如下代码段:
Route::get('/home', function () {
return view('home');
});
在目录resources/views下创建视图文件:home.php,内容如下:
<html>
<body>
<h1>home</h1>
</body>
</html>
打开浏览器访问:http://localhost:801/home
如果上例的代码中需要向视图页传递参数怎么办呢?修改我们的路由代码:
Route::get('/home', function () {
return view('home', ['name' => '张三']);
});
修改视图代码:
<html>
<body>
[<?php echo $name; ?>],您好!
</body>
</html>
再看看访问的效果:
如果视图太多,一般是按模块甚至按功能存放的,在resources/views目录下依次新建目录:public/demo,然后把home.php移到该目录中。
修改上例中的路由代码为:
Route::get('/home', function () {
return view('public.demo.home', ['name' => '张三']);
});
再次访问还是能正常打开页面的。
2.3 转发给Controller的Action处理
Route::get('/home', 'DemoController@home');
这种方式本篇不做详解,将在本系列第四篇文章中说明。
2.4 路由参数
在前文已经说过,路由可以匹配出用户的请求参数,那如何匹配呢?在上例的路由文件中追加代码段:
Route::get('user/{name}', function($name) {
return '用户姓名:'.$name;
});
打开浏览器访问:http://localhost:801/user/jack
那如果是两个参数怎么办呢?修改路由代码:
Route::get('user/{name}/{age}', function($name,$age) {
return '用户姓名:'.$name.',年龄:'.$age;
});
打开浏览器访问:http://localhost:801/user/jack/23
假如age参数不是必须的的呢?再次修改路由代码:
Route::get('user/{name}/{age?}', function($name,$age=null) {
return '用户姓名:'.$name.',年龄:'.$age;
});
访问地址:http://localhost:801/user/jack
2.5 路由参数的约束
在正常情况下,用户访问的一些参数是有一定的规则,比如读取用户信息时的用户ID可能是数字,修改新闻信息时的新闻ID可能是GUID等等。
修改routes.php文件,追加以下代码:
Route::get('new/{id}', function($id)
{
return '新闻ID:'.$id;
})->where('id', '[0-9]+');
打开浏览器访问 http://localhost:801/new/3 是这样的:
可访问 http://localhost:801/new/abc 时则提供页面不存在:
相应的,当同时对多个参数限制时则需要使用数组,修改上例的路由代码:
Route::get('new/{id}/{title}', function($id,$title)
{
return '新闻ID:'.$id.',新闻标题:'.$title;
})->where(['id' => '[0-9]+', 'title' => '[a-z]+']);
访问效果这里就不演示了。
另外,我们可以配置全局的限制条件,打开文件:app/Providers/RouteServiceProviders.php,修改boot方法如下:
public function boot(Router $router)
{
//
$router->pattern('id', '[0-9]+');
parent::boot($router);
}
修改上例中的路由代码为:
Route::get('new/{id}', function($id)
{
return '新闻ID:'.$id;
});
访问效果和上例是一样的,这里不在演示。
2.6 获取路由参数
在routes.php中可以获取路由参数,以此来做其他的操作,修改上例的路由代码:
Route::get('new/{id}', function(Request $request, $id)
{
if ($request->route('id') == '2')
{
return '新闻ID是2';
}else{
return '新闻ID不是2,值是:'.$id;
}
});
在routes.php中<?php后插入新的一行:
use Illuminate\Http\Request;
打开浏览器,分别访问 http://localhost:801/new/2 和 http://localhost:801/new/3 即可看到不同的页面效果。
3 路由群组
3.1 指定中间件
路由群组所接收的第一个参数将为群组下的每一个路由赋值:
Route::group(['middleware' => ['foo', 'bar']], function()
{
Route::get('/', function()
{
// Has Foo And Bar Middleware
});
Route::get('user/profile', function()
{
// Has Foo And Bar Middleware
});
});
上例所示代码,将为其中的2个路由指定两个中间件,中间件的内容将在下章讲解。
3.2 指定命名空间
又或者使用群组指定控制器的命名空间:
Route::group(['namespace' => 'Admin'], function()
{
// Controllers Within The "App\Http\Controllers\Admin" Namespace
Route::group(['namespace' => 'User'], function()
{
// Controllers Within The "App\Http\Controllers\Admin\User" Namespace
});
});
3.3 指定前缀
指定统一的访问前缀:
Route::group(['prefix' => 'admin'], function()
{
Route::get('users', function()
{
// Matches The "/admin/users" URL
});
});
在指定前缀时可以注册一个URL参数:
Route::group(['prefix' => 'accounts/{account_id}'], function()
{
Route::get('detail', function($account_id)
{
//
});
});
也可以对URL参数定义限制:
Route::group([
'prefix' => 'accounts/{account_id}',
'where' => ['account_id' => '[0-9]+'],
], function() {
// Define Routes Here
});
路由还有很多复杂的功能,有待研究。