Laravel学习日记2:路由

所有的 Laravel 路由都在 routes 目录中的路由文件中定义,这些文件都由框架自动加载。routes/web.php 文件用于定义 web 界面的路由。而大多数的应用构建,都是以在 routes/web.php 文件定义路由开始的。因此,本文使用routes/web.php路由文件来进行。

支持的请求方式

本节直接使用5.5文档描述。
路由器允许你注册能响应任何 HTTP 请求的路由:

Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);

有的时候你可能需要注册一个可响应多个 HTTP 请求的路由,这时你可以使用 match 方法,也可以使用 any 方法注册一个实现响应所有 HTTP 请求的路由:

Route::match(['get', 'post'], '/', function () {
    //
});

Route::any('foo', function () {
    //
});

基本路由

构建最基本的路由只需要一个 URI 与一个“闭包”,如下所示:

Route::get('/users', function () {
    return 'hello,world!';
});

这就是最简单的路由实现方式,直接使用一个未声明函数的方法来进行实现。
另外一种比较简单的路由实现方式,则是调用控制器下方法的方式,如下所示:

Route::get('/usres', 'UserController@show');

这个路由调用的就是UserController控制器下的show()方法。

重定向路由

使用Route::redirect可以实现路由的重定向,例如将路由”/baidu”重定向到百度主页:

Route::redirect('/baidu','http://www.baidu.com', 301);

这样,在访问”ip:port/baidu”时,浏览器就会跳转到百度的主页去。
重定向路由还可以将路由重定向到其它已设置的路由上去,例如:

Route::redirect('/badu', '/users', 301);

就是将路由”badu”重定向到了路由”users”上,在访问”ip:port/badu”时,浏览器所展示的页面与直接访问”ip:port/users”是相同的。

视图路由

路由也可以直接返回一个视图,通过Route::view方法来实现,该方法可以接收3个参数,前两个参数为必选参数,第3个参数为可选参数(第3个参数是传递给视图的变量数据)。

Route::view('/users', 'users');
Route::view('/users', 'users', ['name' => 'Taylor']);

如上所示,第1个路由将会返回”users”视图;而第2个路由也会返回”users”视图,不同的是第2个路由中向”users”视图传递了一个变量名为”name”的参数,这样,在”users”视图中,就可以通过”{{ name }}”的方式来获取并展示此变量的值。

参数路由

laravel中的路由参数分为两种:必填参数、可选参数。

必填参数

顾名思义,路由参数中的必填参数就是指在URL中必须存在的参数,如果不存在那程序就会抛出错误。
如下就是一条标准的必填参数路由示例:

Route::get('/bmw/{customer}', function ($customer) {
    return 'Hello,'.$customer;
});

其中,“{customer}”就是一个必填参数,我们使用”ip:port/bmw/biubiubiu”来进行访问,可以得到页面输出:

hello,biubiubiu

可以定义一个或多个必填参数,以下两种方式都可以定义多个参数:

Route::get('/bmw7/{param1}/{param2}', function ($param1, $param2){
        return 'Hello, p1='.$param1.';p2='.$param2;
});

Route::get('/bmw3/{param1}/bmw5/{param2}', function ($param1, $param2){
        return 'hello, p1='.$param1.'; p2='.$param2;
});

其中第一种方法使用”ip:port/bmw7/series7/seeyouagain”来进行访问,可以得到页面输出:

Hello, p1=series7;p2=seeyouagain

而第二种写法使用”ip:port/bmw3/325/bmw5/525”来进行访问,可以得到页面输出:

hello, p1=325; p2=525

可选参数

如果指定的路由参数是可有可无的,那就需要使用可选参数,可选参数通过在参数后面添加“?”来实现。
使用可选参数时需要注意一定要填写function中参数变量的默认值,可选参数使用如下方式定义:

Route::get('/bmw/{customer?}', function ($customer = 'Taylor'){
        return 'hello,'.$customer;
});

以上的路由可以通过”ip:port/bmw”或”ip:port/bmw/world”的方式来访问,如果使用”ip:port/bmw”的方式访问,因为没有相关参数,所以会使用变量默认值“Taylor”;而使用”ip:port/bmw/world”方式访问,则与必填参数相同,会使用“world”来填充变量,依次进行访问后可得到如下页面输出:

hello,Taylor    // 使用"ip:port/bmw"方式
hello,world     // 使用"ip:port/bmw/world"方式

与必填参数相同,可选参数也支持多个参数,但需要注意的是,多个参数中,只有最后一个参数可以设置为可选参数,如果设置前面的参数为可选参数,程序会抛出错误。

Route::get('/bmw3/{param1}/bmw5/{param2?}', function ($param1 = 'testA', $param2 = 'testB'){
        return 'hello, p1='.$param1.'; p2='.$param2;
});

如上路由,在使用”ip:port/bmw3/325/bmw5/”进行访问时,因为变量param2未设置,所以会使用默认值”testB”,执行请求后会得到页面输出为hello, p1=325; p2=testB;而如果使用”ip:port/bmw3/325/bmw5/525”进行访问,就会得到输出hello, p1=325; p2=525
但是如果将“{param1?}”设置为可选参数,然后通过”ip:port/bmw3/bmw5/525”的方式来进行访问,程序就会抛出找不到页面的错误。

正则约束

laravel中的路由参数也支持正则表达式的约束方式,设置了正则约束之后,就只有满足指定约束条件的请求地址才会被定位到该路由进行处理,如下所示:

Route::get('/benz/{id}', function ($id) {
        return 'id = '.$id;
})->where('id', '[0-9]+');

此路由通过where方式指定了路由参数id的正则约束为数字,因此在通过”http:://ip:port/benz/123”来进行请求的时候,能够匹配到该路由(满足了正则约束条件),而通过”http://ip:port/benz/abc“来进行请求时,就不会匹配到该路由(不满足约束条件)。

正则约束也支持同时约束多个路由参数的方式,如下所示:

Route::get('/benz/{id}/{name}', function ($id, $name) {
        return 'id = '.$id.'; name = '. $name;
})->where(['id' => '[0-9]+', 'name' => '[a-zA-Z]+']);

对参数id和name分别设置了不同的正则约束条件,这样,就只有在请求完全符合约束的时候,才会指向此路由。

全局约束

在设置路由时,可能很多路由都会有相同的参数,例如参数id,它们具有相同的约束条件,此时可以使用全局约束的方式来进行配置,配置一次全局生效,而不需要每个路由都去添加正则约束。
使用全局约束时需要修改“app/Providers/RouteServiceProvider.php”文件,在“boot”方法中添加相关约束条件,我们将id和name的约束都放到这里来。

 public function boot()
    {
        Route::pattern('id','[0-9]+');
        Route::pattern('name','[a-zA-Z]+');
        parent::boot();
    }

然后将routes/web.php中的相关路由修改一下,删除掉where:

Route::get('/benz/{id}/{name}', function ($id, $name) {
        return 'id = '.$id.'; name = '. $name;
})

此时,通过“http://ip:port/benz/777/bbq”可以正确指向此路由,而若使用的是不满足参数约束条件的请求,例如“http://ip:port/benz/777/b55”,依然会抛出错误。
只要设置了全局约束,那约束针对的就是每一个相应的参数,参数所在位置对此并无影响。

命名路由

命名路由我认为主要有以下两个作用:
1、用于生成指向该路由的URL地址;
2、用于检测当前路由是否是某个指定的路由。

命名路由也是通过链式方式来进行,使用name来进行命名。

Route::get('/byd', function () {
        $url = route('propro');
        return $url;
})->name('propro');

这里使用了全局辅助函数route来生成了名为”propro”的路由地址,这是命名路由的第一个作用。
第二个作用检测当前路由可以用来实现不同的操作,看下面的例子,添加了3条路由信息,都指向了UserController下的car()方法。

Route::get('/junyue', 'UserController@car')->name('buick');
Route::get('/jiguang', 'UserController@car')->name('landrover');
Route::get('/meidusa', 'UserController@car')->name('snake');

在car()方法中根据路由来进行处理,可以实现不同的逻辑:

 public function car(Request $request){
                $url = $request->url();
                if( $url == route('buick')){
                        return "this is Buick";
                }elseif( $url == route('landrover')){
                        return "this is LANDROVER";
                }else{
                        return "this is car";
                }       
        }

路由组

路由组重点在于这个“组”的概念,将需要操作的路由都添加到这个组里之后,对这个组的操作(添加中间件或使用命名空间)就相当于对组内所有路由的操作,简化了步骤。
路由组使用Route::group来进行定义,格式为Route::group($array, $routes),如下所示定义了一个路由组,当中有两条路由信息。

Route::group(array(), function () {
        Route::get('/cat', function () {
                return 'hello, cat';
        });
        Route::get('/dog', function () {
                return 'hello, dog';
        });
});

路由中间件

路由中间件可以对单条路由进行操作,也可以对路由组进行操作。
对单条路由操作:

Route::get('/huge',function(){})->middleware('auth');
Route::get('/hage', ['middleware' => 'auth', function(){}]);

以上两种定义方法都可以实现对一条路由添加中间件的功能。
对路由组的操作:

Route::group(array('middleware' => 'auth'), function () {
        Route::get('/cat', function () {
                return 'hello, cat';
        });
        Route::get('/dog', function () {
                return 'hello, dog';
        });
});

如上所示,Route::group中的第一个参数数组就是用来定义路由组的共享属性的。

路由命名空间

默认情况下,app/Providers/RouteServiceProvider.php中已经引入了App\Http\Controllers命名空间,所以,只需要指定命名空间App\Http\Controllers之后的部份即可。

Route::group(array('namespace' => 'User'), function () {
        Route::get('/nametest', 'UserController@show');
});

此路由指向的命名空间就是App\Http\Controllers\User,调用的就是App\Http\Controllers\User命名空间下的UserController控制器类中的show方法。

子域名路由

路由组的共享属性中支持子域名的设置,并且允许从子域名中获取部份当作参数来进行使用。

Route::group(array('domain' => '{port}.testapp.com'), function () {
        Route::get('/subtest', function ($port) {
                return 'port = '.$port;
        });
});

路由前缀

路由组的共享属性中支持设置路由前缀,通过prefix来进行标识。

Route::group(array('prefix' => 'diy'), function () {
        Route::get('/subtest', function (){
                return 'Hello,Welcome to china';
        });
});

此路由的请求URL为“http://ip:port/diy/subtest”。

路由模型绑定

待续。

猜你喜欢

转载自blog.csdn.net/ljl890705/article/details/78794099
今日推荐