最适合入门的Laravel初级教程(五)路由控制器关联

本文详细介绍了Laravel中如何创建和组织路由,包括使用控制器、路由组、命名空间以及路由参数的使用。通过路由组简化具有相同前缀的路由,并展示了如何通过`RouteServiceProvider`设置全局路由约束。此外,还讲解了如何获取和处理请求参数,包括`Request`类的使用,如`input`、`all`、`only`和`except`方法。
摘要由CSDN通过智能技术生成

路由咱会创建了;
控制器也有了;
接下来要搞的就是把两者关联起来了;
最适合入门的laravel初级教程(三)
我们讲过 Route 的 get 或者 post 方法第一个参数就是我们要定义的路由;
就是我们在地址栏请求的那段url;
第二个参数可以是一个闭包函数;
里面写请求定义的路由时执行的内容;
上篇文章我们说过;
如果把代码都放这个闭包函数中是臃肿且难以维护的;
所以就需要使用控制器了;
很显然;控制器就是来替代这第二个参数的闭包函数的;
写起来也非常简单直接写控制器名即可;
然后用 @ 符号分割控制器和控制器的方法

Route::get('article/index', 'ArticleController@index');
Route::get('article/create', 'ArticleController@create');
Route::post('article/store', 'ArticleController@store');


可以在控制器中写点内容;

访问定义的路由就可以看到内容了;

一切都是这么的完美;
但是如果你和我一样帅;
额;不是;
如果你和我一样懒且善于总结思考;
你会发现这三条路由都是以 article/ 为前缀的;
在路由中我们应该怎么减少这种重复呢?
这就是我们接着要讲的分组的概念;
路由组就是把一些有相同特性的路由放在一个组里面;
我们先来定义一个前缀路由组;
上面这3条路由就可以改造成这个样子了;

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 即可;

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('admin')->namespace('Admin')->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/Home/TagController.php;
那路由就是这样的了;

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 还有另一种定义路由组的方式;

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 方法;

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

感谢大佬的无私奉献,为我等小白提供简明的学习途径

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值