最适合入门的Laravel初级教程(五)

最适合入门的Laravel初级教程(五)

路由咱会建立了;

控制器也有了;
接下来要搞的就是把二者关联起来了;
最适合入门的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

相关文章
相关标签/搜索