淘先锋技术网

首页 1 2 3 4 5 6 7

1、路由

1.1 默认示例

Laravel中所有路由定义在/app/Http/routes.php文件中,该文件默认定义了应用的首页路由:

Route::get('/', function () {
    return view('welcome');
});

这段代码的意思是:当访问应用首页http://selfstudy.com的时候,返回/resources/views/welcome.blade.php视图中的内容并渲染到浏览器页面中:

 

1.2 POST请求

Route::get('/testPost',function(){
    $csrf_token = csrf_token();
    $form = <<<FORM
        <form action="/hello" method="POST">
            <input type="hidden" name="_token" value="{$csrf_token}">
            <input type="submit" value="Test"/>
        </form>
FORM;
    return $form;
});

Route::post('/hello',function(){
    return "Hello Laravel[POST]!";
});

首先我们定义一个/testPost页面用于提交POST请求表单,在http://selfstudy.com/testPost页面点击“Test”按钮,页面跳转到http://selfstudy.com/hello并显示:

Hello Laravel[POST]!

1.3 match、any

Route::match(['get','post'],'/hello',function(){
   return "Hello Laravel!";
});

当然还使用更方便的any方法匹配所有请求方式:

Route::any('/hello',function(){
    return "Hello Laravel!";
});

效果都一样。

2、路由参数

2.1 必选参数

Route::get('/hello/{name}',function($name){
    return "Hello {$name}!";
});

在浏览器中访问http://selfstudy.com/hello/yyyyk输出:

Hello yyyyk

当然还可以指定多个参数:

Route::get('/hello/{name}/by/{user}',function($name,$user){
    return "Hello {$name} by {$user}!";
});

这样在浏览器中访问http://selfstudy.com/hello/yyyyk/by/A则会输出:

Hello yyyyk by A!

注意以上参数是必选的,如果没有输入参数会抛出MethodNotAllowedHttpExceptionNotFoundHttpException异常。

此外闭包函数中的参数与路由参数一一对应。

2.2 可选参数

有时候我们并不总是想要输入对应参数,我们通过这种方式来定义:

Route::get('/hello/{name?}',function($name="yyk"){
    return "Hello {$name}!";
});

我们同时为可选参数指定了默认值,这样当我们访问http://selfstudy.com/hello时输出:

Hello yyk!

当我们访问http://selfstudy.com/hello/yykkk的时候输出:

Hello yykkk!

2.3 正则表达式过滤

有时候我们希望对路由有更加灵活的条件约束,可以通过正则表达式来实现:

Route::get('/hello/{name?}',function($name="Yykk"){
    return "Hello {$name}!";
})->where('name','[A-Za-z]+');

该条件约束意味着$name参数只能包含大小写字母,如果包含数字或中文就会抛出NotFoundHttpException异常。

如果我们想要在全局范围内对参数进行条件约束,可以在RouteServiceProviderboot方法中做如下定义:

public function boot(Router $router)
{
    $router->pattern('name','[A-Za-z]+');
    parent::boot($router);
}

我们访问http://selfstudy.com/hello/yy123时一样会抛出NotFoundHttpException异常。这意味着boot方法定义的参数条件约束将会应用到所有包含该参数的路由中。

3、路由命名

3.1 基本使用

我们使用as关键字为路由命名

Route::get('/test/routename',['as'=>'name', function(){
   return 'Hello Routename!'; 
}]);

路由命名可以让我们在使用route函数生成指向该路由的URL或者生成跳转到该路由的重定向链接时更加方便:

Route::get('/testNamedRoute',function(){
   return route('name');
});

我们在浏览器中访问http://selfstudy.com/testNamedRoute时输出http://selfstudy.com/testNamedRoute,然后我们修改上述闭包内代码:

Route::get('/testNamedRoute',function(){
    return redirect()->route('name');
});

再次在浏览器中访问http://selfstudy.com/testNamedRoute时会跳转到http://selfstudy.com/test/routename。并且输出Hello Routename!

我们甚至还可以在使用带参数的路由命名:

Route::get('/hello/routename/{id}',['as'=>'name',function($id){
    return 'Hello routename'.$id.'!';
}]);

对应的测试路由定义如下:

Route::get('/testNamedRoute',function(){
    return redirect()->route('name',['id'=>1]);
});

这样,当我们在浏览器中访问http://selfstudy.com/testNamedRoute时会跳转到http://selfstudy.com/test/routename/1

再来看一个更复杂的例子,使用路由分组时如何定义路由命名?官网文档提供的例子如下:

Route::group(['as' => 'admin::'], function () {
    Route::get('dashboard', ['as' => 'dashboard', function () {
        //
    }]);
});

Route门面的group方法中使用一个as关键字来指定该路由群组中所有路由的公共前缀,然后在里面每个路由中使用as关键字为该路由命名。

这样我们可以通过如下方式来生成该路由URL:

Route::get('/testNamedRoute',function(){
    return route('admin::dashboard');
});

4、路由分组

路由分组就是将一组拥有相同属性(中间件、命名空间、子域名、路由前缀等)的路由使用Route门面的group方法聚合起来

4.1 命名空间

默认情况下,routes.php中的定义的控制器位于App\Http\Controllers命名空间下,所以如果要指定命名空间,只需指定App\Http\Controllers之后的部分即可:


Route::group(['namespace' => 'Test'], function(){
    // 控制器在 "App\Http\Controllers\Test" 命名空间下

    Route::group(['namespace' => 'Files'], function()
    {
        // 控制器在 "App\Http\Controllers\Test\Files" 命名空间下
    });
});

4.2 路由前缀

如果路由群组中的所有路由包含统一前缀,则我们可以通过在group方法中设置prefix属性来指定该前缀:

Route::group(['prefix'=>'test'],function(){
    Route::get('write',function(){
        return "Write test";
    });
    Route::get('update',function(){
        return "Update test";
    });
});

这样我们就可以通过http://selfstudy.com/test/write或者http://selfstudy.com/test/update来访问对应的操作。

我们甚至还可以在路由前缀中指定参数:

Route::group(['prefix'=>'test/{num}'],function(){
    Route::get('write',function($num){
        return "Write Test{$num}";
    });
    Route::get('update',function($num){
        return "Update Test{$num}";
    });
});

这样我们在浏览器中访问http://selfstudy.com/test/5.1/write,则对应会输出:

Write Test 5.1

4.3 中间件

首先我们在应用根目录下运行如下Artisan命令生成一个测试用的中间件TestMiddleware

打开命令行 win+R 到项目根目录(也就是artisan命令所在目录)执行以下命令

php artisan make:middleware TestMiddleware

这样会在/app/Http/Middleware目录下生成一个TestMiddleware.php文件,打开该文件编辑TestMiddleware类的handle方法如下:

public function handle($request, Closure $next)
{
    if($request->input('age')<18)
        return redirect()->route('refuse');
    return $next($request);
}

我们在中间件中定义这段业务逻辑的目的是年龄18岁以下的未成年人不能访问。

然后我们打开/app/Http/Kernel.php文件,新增TestMiddlewareKernel$routeMiddleware属性:

protected $routeMiddleware = [
    'auth' => \App\Http\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
    'test' => \App\Http\Middleware\TestMiddleware::class,
];

接下来我们在routes.php中定义路由如下:

Route::group(['middleware'=>'test'],function(){
    Route::get('/write/middleware',function(){
        //使用Test中间件
    });
    Route::get('/update/middleware',function(){
       //使用Test中间件
    });
});

Route::get('/age/refuse',['as'=>'refuse',function(){
    return "未成年人禁止入内!";
}]);

这样当我们在浏览器中访问http://selfstudy.com/write/middleware?age=15或者http://selfstudy.com/update/middleware?age=15时就会跳转到http://selfstudy.com/age/refuse,并显示:

未成年人禁止入内!