设为首页 加入收藏

TOP

laravel5.5源码笔记(六、中间件)(一)
2019-08-23 00:40:25 】 浏览:60
Tags:laravel5.5 源码 笔记 中间件

laravel中的中间件作为一个请求与响应的过滤器,主要分为两个功能。

1、在请求到达控制器层之前进行拦截与过滤,只有通过验证的请求才能到达controller层

2、或者是在controller中运算完的数据或页面响应返回前进行过滤,通过验证的响应才能返回给客户端

中间件一般通过artisan命令创建

php artisan make:middleware 中间件名称

命令行创建的中间件会保存在/app/Http/Middleware文件夹里

这些中间件需要手动添加在/app/Http/Kernel.php文件的配置中,这个文件继承了kernel核心,在应用入口初始化kernel核心时,vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php这个kernel文件中的配置便覆盖了kernel核心中的相关配置,其中当然便包括了middleware中间件。我们可以在kernel类的构造方法第一行添加打印语句,分别打印$this->middleware,$this->middlewareGroups然后我们就会看见之前写在/app/Http/Kernel.php文件中的中间件了。

不过不止这里一处,在路由加载的时候,也会加载一次系统默认的web数组中的中间件,在返回响应对象的时候进行过滤,这个稍后再看。

接下来看一下中间件是在哪里开始过滤的,在第一篇关于入口文件的博文中,我们了解到laravel是从kernel核心中的handle方法开始的。

    public function handle($request)
    {
        try {
            //启用http方法覆盖参数
            $request->enableHttpMethodParameterOverride();
            //通过路由发送请求
            $response = $this->sendRequestThroughRouter($request);
        } catch (Exception $e) {
            $this->reportException($e);

            $response = $this->renderException($request, $e);
        } catch (Throwable $e) {
            $this->reportException($e = new FatalThrowableError($e));

            $response = $this->renderException($request, $e);
        }

        $this->app['events']->dispatch(
            new Events\RequestHandled($request, $response)
        );

        return $response;
    }

    protected function sendRequestThroughRouter($request)
    {
        //将请求存入容器
        $this->app->instance('request', $request);
        //清除facade门面
        Facade::clearResolvedInstance('request');
        //初始化引导
        $this->bootstrap();
        //让请求进入中间件
        return (new Pipeline($this->app))
                    ->send($request)
                    ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
                    ->then($this->dispatchToRouter());
    }

 kernel核心的sendRequestThroughRouter方法中最后的return 语句,便开始使用中间件来对系统接到的请求开始进行过滤了。

上一篇博文中,我们提到了装饰模式与laravel在此基础上变种来的管道模式,便是在这里开始运用。

从Pipeline对象一路跳转,发现这个对象的基类为laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php。管道对象的构造方法把laravel系统容器传入了其中。这里不再赘述管道模式的原理,直接来看关键方法then。

 1     public function then(Closure $destination)
 2     {
 3         //array_reduce — 用回调函数迭代地将数组简化为单一的值
 4         $pipeline = array_reduce(
 5             //array_reverse将数组反向排序,$this->carry()返回一个闭包函数用来迭代
 6             array_reverse($this->pipes), $this->carry(), $this->prepareDestination($destination)
 7         );
 8 
 9         return $pipeline($this->passable);
10     }
11 
12     protected function carry()
13     {
14         return function ($stack, $pipe) {
15             return function ($passable) use ($stack, $pipe) {
16                 if (is_callable($pipe)) {
17                     // If the pipe is an instance of a Closure, we will just call it directly but
18                     // otherwise we'll resolve the pipes out of the container and call it with
19                     // the appropriate method and arguments, returning the results back out.
20                     return $pipe($passable, $stack);
21                 } elseif (! is_object($pipe)) {
22                     //解析字符串
23                     list($name, $parameters) = $this->parsePipeString($pipe);
24 
25                     // If the pipe is a string we will parse the string and resolve the class out
26                     // of the dependency injection container. We can then build a callable and
27                     // execute the pipe function giving in the parameters that are required.
28                     //从容器中取出相应的对象
29                     $pipe = $this->getContainer()->make($name);
30                     $parameters = array_merge([$passable, $stack], $paramet
首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇PHP删除当前目录及其目录下的所有.. 下一篇苍了个天了~网站被挂马!

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目