控制器也有了;
接下来要搞的就是把二者关联起来了;
最适合入门的laravel初级教程(三)
咱们讲过 Route 的 get 或者 post 方法第一个参数就是咱们要定义的路由;
就是咱们在地址栏请求的那段url;
第二个参数能够是一个闭包函数;
里面写请求定义的路由时执行的内容;
上篇文章咱们说过;
若是把代码都放这个闭包函数中是臃肿且难以维护的;
因此就须要使用控制器了;
很显然;控制器就是来替代这第二个参数的闭包函数的;
写起来也很是简单直接写控制器名便可;
而后用 @
符号分割控制器和控制器的方法php
Route::get('article/index', 'ArticleController@index'); Route::get('article/create', 'ArticleController@create'); Route::post('article/store', 'ArticleController@store');
能够在控制器中写点内容;
访问定义的路由就能够看到内容了;
一切都是这么的完美;
可是若是你和我同样帅;
额;不是;
若是你和我同样懒且善于总结思考;
你会发现这三条路由都是以 article/
为前缀的;
在路由中咱们应该怎么减小这种重复呢?
这就是咱们接着要讲的分组的概念;
路由组就是把一些有相同特性的路由放在一个组里面;
咱们先来定义一个前缀路由组;
上面这3条路由就能够改形成这个样子了;laravel
Route::prefix('article')->group(function () { Route::get('index', 'ArticleController@index'); Route::get('create', 'ArticleController@create'); Route::post('store', 'ArticleController@store'); });
若是控制器都直接放在 app/Http/Controllers 目录下的话;
那维护起来也开始略头疼了;
因而就能够为控制器分目录存放了;
好比说我要建一个 app/Http/Controllers/Admin/ArticleController.php;
再建一个 app/Http/Controllers/Home/ArticleController.php ;
命令行也是能够加目录的;数据库
php artisan make:controller Admin/ArticleController --resource
php artisan make:controller Home/ArticleController --resource
再在新建的控制器中写点内容加以区分;
这种多级目录是不须要指明目录的;
只须要指明相对于app/Http/Controllers 目录的 namespace 便可;bash
Route::prefix('admin/article')->namespace('Admin')->group(function () { Route::get('index', 'ArticleController@index'); Route::get('create', 'ArticleController@create'); Route::post('store', 'ArticleController@store'); });
group 是能够嵌套的;
那么上面这样的路由还能够改造下;闭包
Route::prefix('home')->namespace('Home')->group(function () { Route::prefix('article')->group(function () { Route::get('index', 'ArticleController@index'); Route::get('create', 'ArticleController@create'); Route::post('store', 'ArticleController@store'); }); });
访问起来就是这样的了;
由于 Admin 目录下咱们还会建立更多的路由器;
因此;咱们应该使用 group 嵌套的这种方式;
好比说咱们再有一个 app/Http/Controllers/Admin/TagController.php;
那路由就是这样的了;app
Route::prefix('home')->namespace('Home')->group(function () { Route::prefix('article')->group(function () { Route::get('index', 'ArticleController@index'); Route::get('create', 'ArticleController@create'); Route::post('store', 'ArticleController@store'); }); Route::prefix('tag')->group(function () { Route::get('index', 'TagController@index'); Route::get('create', 'TagController@create'); Route::post('store', 'TagController@store'); }); });
除了文档上讲的这种方式;
其实之前版本的 laravel 还有另外一种定义路由组的方式;ide
Route::group(['prefix'=>'admin', 'namespace'=>'Admin'], function () { Route::group(['prefix'=>'article'], function () { Route::get('index', 'ArticleController@index'); Route::get('create', 'ArticleController@create'); Route::post('store', 'ArticleController@store'); }); });
就是把 prefix 和 namespace 这些都做为 group 方法的第一个参数;
不过如今不推荐这种写法了;
不过由于不少之前的项目都是这样写的;
这里讲一下让童鞋们查看别人之前的项目的时候能理解而不迷茫;函数
为了讲解的简单;
咱们回到 app/Http/Controllers/ArticleController.php 文件接着往下看;
会发现命令行建立的控制器里面有个 edit 方法;post
public function edit($id) { // }
edit 方法有个 $id 参数;
这个参数是干什么用的呢?
经过名字咱们很容易就明白这是用来修改数据的;
id 通常又是数据库的自增字段;
那这就是要修改指定 id 的数据了;
可是这个 id 是哪传来的呢?
下面就到了讲解路由参数的时候了;
定义路由的时候咱们是能够定义路由参数的;
咱们接着上面的路由加一个 edit 的;测试
Route::prefix('article')->group(function () { Route::get('index', 'ArticleController@index'); Route::get('create', 'ArticleController@create'); Route::post('store', 'ArticleController@store'); Route::get('edit/{id}', 'ArticleController@edit'); });
咱们在定义路由的时候用花括号包一个变量名;
那这个变量就能够直接传到控制器方法中;
而后在地址栏传什么控制器中就能够接到什么;
为了方便测试咱们在这个方法中返回 id ;
public function edit($id) { return '地址栏传的参数是:'.$id; }
携带着路由参数经过路由访问这个方法;
这里面有个容易栽跟头的地方;
就是控制器中的参数名跟路由参数名不是必须相同的;
也就是说我这样写也是能够的;
public function edit($a) { return '地址栏传的参数是:'.$a; }
一个路由参数的时候这倒不会以为什么;
一旦定义多个路由参数的时候;
这个坑就真的坑了;
Route::prefix('article')->group(function () { // ... Route::get('edit/{id}/{name}', 'ArticleController@edit'); });
在控制器中获取路由参数的时候;
public function edit($name, $id) { return 'id是:' . $id . '<br>name是:' . $name; }
访问 http://bjyblog.test/article/edit/666a/白俊遥
;
在你觉得闭着眼都知道结果的时候;
一只硕大的幺蛾子飞了过来;
你发现 id 和 name 没对上;
该敲黑板画重点了筒子们;
路由参数中的第一个参数对应控制器中的第一个路由参数;
以此类推;
在控制器中路由参数跟参数名是不要紧的;
只跟顺序有关;
再个 id 通常都是纯数字;
这里却传了字母 ;
咱们应该怎么约束下 id 呢?
laravel 方方面面都为咱们考虑到了;
咱们加个 where 就好了;
Route::prefix('article')->group(function () { // ... Route::get('edit/{id}/{name}', 'ArticleController@edit')->where('id', '[0-9]+'); });
这样就只能传数字了;
其实大多的表都是用 id 作主键的;
若是每一个路由都手动定义一遍约束;
那也是挺麻烦的;
laravel 又一次方方面面都为咱们考虑到了;
找到 app/Providers/RouteServiceProvider.php 这个文件;
在 boot 方法中能够定义全局约束;
public function boot() { Route::pattern('id', '[0-9]+'); parent::boot(); }
这样就不须要为每条带 id 参数的路由定义约束了;
之后全部带 id 参数的路由就只能传数字了;
不懂这个 RouteServiceProvider 的话不要紧不要纠结在这;
就先当是固定用法;
之后慢慢懂;
路由参数?请求参数?傻傻分不清楚;
举个栗子;
Route::prefix('article')->group(function () { // ... Route::get('edit/{id}/{name}', 'ArticleController@edit'); });
bjyblog.test/article/edit/666
/白俊遥
?music
=越过山丘&book
=平凡世界
id 和 name 就是路由参数;
music 和 book 就是请求参数;
路由参数的获取咱们已经会了;
那请求参数怎么获取呢?
咱们再回控制器中转悠转悠还会发现 update 方法;
public function update(Request $request, $id) { // }
这个 Request $request
就是咱们用来获取请求参数的关键;
它的意思是向控制器的方法传一个 $request
它是一个 Request
类;
咱们能够把咱们的 edit 方法也加个 $request ;
public function edit(Request $request, $id, $name) { $music = $request->input('music'); $book = request()->input('book'); $str = <<<php id: $id <br> name: $name <br> music: $music <br> book: $book <br> php; return $str; }
这个 Request $request 是不会影响路由参数的顺序的;
它放前放后都是能够的;
咱们访问这个方法并携带请求参数;
Request 类有一个 input 方法;
把要获取的参数名传给它就能够了;
我上面示例中还用了个 request() 函数;
它跟 Request $request 效果是同样的;
$request 能够方便复用;
因此在控制器中更推荐使用 $request ;
若是传的请求参数比较多的时候;
这样一个一个的获取仍是麻烦;
Request 还有个 all 方法就能够获取所有的请求参数;
public function edit(Request $request, $id, $name) { dump($request->all()); }
dump 是 laravel 自带的一个打印函数;
就是 php 自带的 var_dump 函数的升级版;
打印出来的效果是这样的;
若是想打印数据并 die 掉可使用 dd()
函数;
若是只想从一大堆请求参数中获取指定的请求参数
Request 还有个 only 方法;
public function edit(Request $request, $id, $name) { dump($request->only('music', 'book')); }
那若是想排除某个参数剩下的全要呢?
Request 还有个 except 方法;
public function edit(Request $request, $id, $name) { dump($request->except('music')); }
再次赞美 laravel 的体贴周到;
本文为白俊遥原创文章,转载无需和我联系,但请注明来自白俊遥博客 https://baijunyao.com