这一节学习路由模型绑定(Route Model Binding)。
打开 ArticlesController.php 文件,如果仔细看代码的话,会发现我们的函数中多次出现了 $article = Article::findOrFail($id);
这一段代码。如果我们的程序能够自动找到 ID
对应的记录,并让 Laravel 自动查询,这是不是非常的棒?这就是路由模型绑定会做到的事情。
查看程序目录,我们会发现一个 app/Providers 文件夹,这里面的文件定义了 Laravel 如何创建或者启动组件。app/Providers/RouteServiceProvider.php 就是定义程序路由如何启动的。
打开 routes.php ,可以看到 Route::get('contact', 'PagesController@contact');
路由指向的是 PagesController
控制器,而该控制器的命名空间是 namespace App\Http\Controllers;
。如果我们每次都这么写的话会很麻烦,所以我们把它指定为默认值,该默认值就是通过 app/Providers/RouteServiceProvider.php 文件中的 protected $namespace = 'App\Http\Controllers';
来定义的。该文件中的 map()
方法中实现了引入 routes.php 的功能。而我们需要关注的是 boot()
方法,我们在该方法中添加代码:
public function boot(Router $router) { parent::boot($router); $router->model('articles', 'App\Article'); }
其中 model()
的参数 articles
是路由中的 key
值。例如 routes.php 中定义了路由 Route::get('foo/{bar}', function(){});
,则 key
值就是 bar
。我们在命令行执行下面的命令:
D:\wamp\www\laravel5>php artisan route:list
可以看到
articles | articles.index articles/create | articles.create articles | articles.store articles/{articles} | articles.show articles/{articles}/edit | articles.edit articles/{articles} | articles.update articles/{articles} | articles/{articles} | articles.destroy
Articles控制器中的 key
值为 articles
,所以在 boot()
方法中我们写的就是 articles
。
经过上面的修改,Articles 控制器中的 show($id)
方法的参数 $id
已经不再是文章的ID了,可以在修改 show()
方法来看一下:
public function show($id){ dd($id); $article = Article::findOrFail($id); return view('articles.show', compact('article')); }
现在随便打开一篇文章的详细页,可以看到输出了下面的文章类:
因此,我们可以直接修改 show()
方法为:
public function show(Article $article){ return view('articles.show', compact('article')); }
再次刷新页面,可以看到,直接显示的文章详细页,与之前的完全相同。同样的方法修改 edit()
与 update()
方法:
public function edit(Article $article){ return view('articles.edit', compact('article')); } public function update(Article $article, ArticleRequest $request){ $article->update($request->all()); return redirect('articles'); }
然后访问 http://laravel.dev/articles/create 与 http://laravel.dev/articles/1/edit 来验证刚才修改的功能是否正常。如果代码跟上面一样的话,应该是没有问题的。
另外,如果我们想做一些更多的操作,如添加 where()
条件等等,则可以修改 boot()
中的内容,使用 bind()
方法来返回结果:
public function boot(Router $router) { parent::boot($router); $router->bind('articles', function($id){ return \App\Article::published()->findOrFail($id); }); //$router->model('articles', 'App\Article'); }
上面的方法会返回一样的结果。
上面就是路由模型绑定的内容,本节就到这里。
该篇属于专题:《Laravel 5 基础视频教程学习笔记》
wenber 2015/07/08 19:14
楼主,还有吗,跟着你的教程走的,看的意犹未尽啊.
Specs 2015/07/08 21:55
@ 那个视频教程还有,最近没空学。。
xoolee 2016/02/19 23:24
视频是哪里的啊,能罚下地址吗,我也看看
Specs 2016/02/20 12:29
@ 这个 laracasts.com/series/laravel-5-fundamentals
看了几次没看懂 2016/04/08 12:10
articles/{articles} Articles控制器中的 key 值为 articles,所以在 boot() 方法中我们写的就是 articles 。不懂是意思,到底是哪个articles?前面的不是括号里的?
Specs 2016/04/08 13:56
@ 括号里
samwu 2017/07/02 07:25
需要把 routes.php 里面Route::get('articles/{id}','ArticlesController@show');改成Route::get('articles/{articles}','ArticlesController@show'); 这个{} 里面的articles 是key,需要和RouteServiceProvider.php 里面的 $router->model('articles', 'App\Article'); 第一个参数 articles 一样,否则是显示不出结果的。如果是 dd($id)的话,只是出来一个“id”。如果显示整个article 内容就是空白。搞死了。很难调试哦。
Specs 2017/07/02 22:42
@ 新版本里面其实已经不需要这么写了~