Lumen开发:lumen源码解读之初始化(3)——单例(singleton)与中间件(Middleware)

版权声明:本文为博主原创文章,未经博主允许不得转载。

今天来讲讲Lumen的singleton和Middleware,先来看看起始文件bootstrap/app.php

/ *
| --------------------------------------------------------------------------
|登记容器绑定
| --------------------------------------------------------------------------
|
|现在我们将登记在服务容器几绑定。我们将
|登记异常处理程序和控制台的内核。您可以添加
|自己绑定在这里如果你喜欢或者你可以做一个文件。
|
* /
$app->singleton(
    Illuminate\Contracts\Debug\ExceptionHandler::class,
    App\Exceptions\Handler::class
);

$app->singleton(
    Illuminate\Contracts\Console\Kernel::class,
    App\Console\Kernel::class
);

这部分是注册绑定了异常处理类和控制台内核类。好像Kernel在Lumen的重要性不如Laravel。

那我们先来分析异常处理的绑定吧,当访问到Illuminate\Contracts\Debug\ExceptionHandler::class接口时,比如

    /**
     * Get the exception handler from the container.(从容器中获取异常处理程序。)
     *
     * @return mixed
     */
    protected function resolveExceptionHandler()
    {
        if ($this->bound('Illuminate\Contracts\Debug\ExceptionHandler')) {
            return $this->make('Illuminate\Contracts\Debug\ExceptionHandler');
        } else {
            return $this->make('Laravel\Lumen\Exceptions\Handler');
        }
    }

会自动绑定到App\Exceptions\Handler::class来处理

 如果

/* $app->singleton(
    Illuminate\Contracts\Debug\ExceptionHandler::class,
    App\Exceptions\Handler::class
); */
$app->singleton(
    Illuminate\Contracts\Debug\ExceptionHandler::class,
    Laravel\Lumen\Exceptions\Handler::class
);

就会由Illuminate\Contracts\Debug\ExceptionHandler::class来处理了。

顺便讲一下另一种单例注册

    /**
     * Register container bindings for the application.(为应用程序注册容器绑定。)
     *
     * @return void
     */
    protected function registerDatabaseBindings()
    {
        $this->singleton('db', function () {
            return $this->loadComponent(
                'database', [
                    'Illuminate\Database\DatabaseServiceProvider',
                    'Illuminate\Pagination\PaginationServiceProvider',
                ], 'db'
            );
        });
    }

这是前面讲数据库初始化时有提到的,这里有两点不一样的地方,第一个参数$abstract不是接口,而是别名‘db’,第二个参数$concrete不是类,而是闭包了,会直接绑定。

(注:如果不是传闭包的话,会对每个绑定的类都包一层闭包,只有服务容器解析时运行,实现了懒加载)。

 

接下来是中间件

/ *
| --------------------------------------------------------------------------
|登记中间件
| --------------------------------------------------------------------------
|
|接下来,我们将与申请登记的中间件。这些可以
|全球中间件运行的每一个请求之前和之后的成
|路线或中间件,会被分配到一些特定的路线。
|
* /

$app->middleware([
    App\Http\Middleware\ExampleMiddleware::class
]);

$app->routeMiddleware([
    //'auth' => App\Http\Middleware\Authenticate::class,
    'auth' => App\Http\Middleware\AuthUser::class
]);
$app->middleware()创建的中间件每次请求都会先过一遍,可以在里面做一些请求验证
namespace App\Http\Middleware;

use Closure;

class ExampleMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if ($request->input('id') <= 10) {
            //echo '$_GET["id"] is litter than 10';exit;
        }

        return $next($request);
    }
}
$app->routeMiddleware(),是指定路由会过的中间件,这里我把路由用户验证中间件改了位置
$app->group(['middleware' => 'auth'], function ($app){
     $app->get('user/data','UserController@UserData');
}

访问http;//.../user/data或指定路由,会先过App\Http\Middleware\AuthUser

AuthUser.php

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Contracts\Auth\Factory as Auth;

class AuthUser
{
    /**
     * The authentication guard factory instance.
     *
     * @var \Illuminate\Contracts\Auth\Factory
     */
    protected $auth;

    /**
     * Create a new middleware instance.
     *
     * @param  \Illuminate\Contracts\Auth\Factory  $auth
     * @return void
     */
    public function __construct(Auth $auth)
    {
        $this->auth = $auth;
    }

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string|null  $guard
     * @return mixed
     */
    public function handle($request, Closure $next, $guard = null)
    {
        
        $token = $request->input('token');
        
        if(!$token){
            echo '请登录!';
        }

     //这里可以写一些对应的认证 return $next($request); } }

多用户就多添加绑定几个中间件即可,如AuthAdmin.php ...

Lumen技术交流群:310493206

 版权声明:本文为博主原创文章,未经博主允许不得转载。

posted @ 2017-09-21 15:44  程序生(Codey)  阅读(1149)  评论(0编辑  收藏  举报