文档章节

Laravel源码入门-启动引导过程(五)$kernel->handle($request)

zhmsong
 zhmsong
发布于 2017/05/14 17:20
字数 780
阅读 430
收藏 0
点赞 0
评论 0

接上文,《Laravel源码入门-启动引导过程(四)app/Http/Kernel.php》,说,Kernel 做了两件事,第一个是定义 $bootstraps[],做好了 boot 系统的准备,第二个是定义 各种 middleware,这些都对 $request 进行加工、处理、甄选、判断,最终为可以形成正确的、有效的 $response 做准备,都完成后,进行了 index.php 中的 $kernel->handle($request),返回 $response。

仔细分析发现,public/index.php 中 $kernel 在make() 时,真的只是做了准备,真正的载入环境变量(.env)、根据配置载入 Service Providers 等,实际在 $kernel->handle($request) 语句中进行。先贴出加入测试 echo 记录下的载入过程结果。

// 开始 public/index.php

$app = require_once __DIR__.'/../bootstrap/app.php' 

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class); 

start-->$response = $kernel->handle() 

// 进入 Illuminate/Foundation/Http/Kernel.php

Foundation/Http/Kernel::handle() 
Foundation/Http/Kernel::sendRequestThroughRouter() 
Foundation/Http/Kernel::bootstrap() 

// 进入 Illumniate/Foundation/Application.php

Foundation/Application::bootstrapWith($bootstrapWith) 

Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables

Illuminate\Foundation\Bootstrap\LoadConfiguration
reading config/app.php 

Illuminate\Foundation\Bootstrap\HandleExceptions
Illuminate\Foundation\Bootstrap\RegisterFacades
Illuminate\Foundation\Bootstrap\RegisterProviders
Illuminate\Foundation\Bootstrap\BootProviders

// 回到 public/index.php

end<---$response = $kernel->handle() 

下面具体看一下 Illuminate\Foundation\Http\Kernel.php 的 handle() 及相关代码片段。

// Illuminate\Foundation\Http\Kernel.php 片段

    /**
     * The bootstrap classes for the application.
     * 引导类,起引导作用的类
     *
     * @var array
     */
    protected $bootstrappers = [
        // 载入服务器环境变量(.env 文件)
        \Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables::class,
        // 载入配置信息(config 目录)
        \Illuminate\Foundation\Bootstrap\LoadConfiguration::class,
        // 配置如何处理异常
        \Illuminate\Foundation\Bootstrap\HandleExceptions::class,
        // 注册 Facades
        \Illuminate\Foundation\Bootstrap\RegisterFacades::class,
        // 注册 Providers
        \Illuminate\Foundation\Bootstrap\RegisterProviders::class,
        // 启动 Providers
        \Illuminate\Foundation\Bootstrap\BootProviders::class,
    ];

    // 此处省略无关代码

    /**
     * Handle an incoming HTTP request. 处理请求的 handle()
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function handle($request)
    {
        echo 'Foundation/Http/Kernel::handle() <br />';
        try {
            $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);
        }

        event(new Events\RequestHandled($request, $response));

        return $response;
    }

    /**
     * Send the given request through the middleware / router.
     * 将请求发送至中间件、路由处理。
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    protected function sendRequestThroughRouter($request)
    {
        echo 'Foundation/Http/Kernel::sendRequestThroughRouter() <br />';

        $this->app->instance('request', $request);

        Facade::clearResolvedInstance('request');

        // Kernel 要启动引导
        $this->bootstrap();

        return (new Pipeline($this->app))
                    ->send($request)
                    ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
                    ->then($this->dispatchToRouter());
    }

    /**
     * Bootstrap the application for HTTP requests.
     * 启动引导(requests 驱动)
     *
     * @return void
     */
    public function bootstrap()
    {
        echo 'Foundation/Http/Kernel::bootstrap() <br />';

        if (! $this->app->hasBeenBootstrapped()) {
            // 使用 Application 的 bootstrapWith()方法启动引导
            // 参数是 Kernel 中的 bootstrapers[]。
            $this->app->bootstrapWith($this->bootstrappers());
        }
    }

=== 总结 ===

如先期描述的 handle() 通过 sendRequestThroughtRouter($request) 处理请求,返回 $response,途中进行了 启动引导,$this->bootstrap(),进一步调用 Application 的 bootstrapWith(),将自己定义的 bootstrapper[] 传入,这个 bootstrappers[] 如前定义,包括了载入服务器环境变量、配置信息、服务提供者、异常处理等。一切结束后,没有抛出异常的话,返回 public/index.php,正如开始的 echo 记录一样。

附:Application 中 bootstrapWith() 代码

// Illuminate\Foundation\Application.php 代码片段

    /**
     * Run the given array of bootstrap classes.
     *
     * @param  array  $bootstrappers
     * @return void
     */
    public function bootstrapWith(array $bootstrappers)
    {
        echo 'Foundation/Application::bootstrapWith($bootstrapWith) <br />';
        $this->hasBeenBootstrapped = true;

        foreach ($bootstrappers as $bootstrapper) {
            echo $bootstrapper . '<br />';
            
            $this['events']->fire('bootstrapping: '.$bootstrapper, [$this]);

            // 解析每个 $bootstrapper,由调用他们自身的 bootstrap(),引导。
            $this->make($bootstrapper)->bootstrap($this);

            $this['events']->fire('bootstrapped: '.$bootstrapper, [$this]);
        }
    }

 

© 著作权归作者所有

共有 人打赏支持
zhmsong
粉丝 41
博文 126
码字总数 65130
作品 0
海淀
程序员
Laravel 5.1 源码阅读

安装,和创建项目,都是通过Composer,简单,略过。 Entry && Kernel 网站入口文件,${Laravel-project}/public/index.PHP: 生成Request,处理Request(),生成Response,发送Resonse。常规...

botkenni
2016/10/09
25
0
Laravel5.3之Middleware源码解析

说明:本文主要学习Laravel的Middleware的源码设计思想,并将学习心得分享出来,希望对别人有所帮助。Laravel5.3之Decorator Pattern已经聊过Laravel使用了Decorator Pattern来设计Middlewar...

botkenni
2016/10/27
37
0
Laravel源码分析——一次Http请求到响应

1前言 在FastCGI协议下工作的php-fpm, 使用持续的进程来处理一连串的请求, 具体到某个请求的解析流程的时候, 如果不考虑扩展的方式, 基本上都是顺序的解析处理. 所以就算复杂如Laravel框架,...

hisense20112784
2017/08/22
0
0
Laravel5.3之bootstrap源码解析

说明:Laravel在把Request通过送入中间件Middleware和路由Router之前,还做了程序的启动Bootstrap工作,本文主要学习相关源码,看看Laravel启动程序做了哪些具体工作,并将个人的研究心得分享...

botkenni
2016/10/28
363
0
Laravel框架一:原理机制篇

http://www.cnblogs.com/XiongMaoMengNan/p/6644892.html Laravel作为在国内国外都颇为流行的PHP框架,风格优雅,其拥有自己的一些特点。 一. 请求周期   Laravel 采用了单一入口模式,应用...

hisense20112784
2017/08/11
0
0
laravel 有些路由报404 框架里没有记录异常,apache 里面体现出来了

[Thu Jul 02 21:00:30.574446 2015] [:error] [pid 2640:tid 760] [client ::1:49859] PHP Fatal error: Uncaught exception 'ErrorException' with message 'is_file(): Unable to find the......

杨太化
2015/07/02
906
2
Laravel5.3之Session源码解析(下)

说明:在中篇中学习了session的CRUD增删改查操作,本篇主要学习关闭session的相关源码。实际上,在Laravel5.3中关闭session主要包括两个过程:保存当前URL到session介质中;在Response Head...

botkenni
2016/11/19
56
0
laravel 源码解读

date: 2017-12-10 22:24:18 title: laravel 源码解读 yii/laravel 的源码质量超高, phper 一定要好好读一读 源码解读: http://naotu.baidu.com/file/9d4b5ab081c174ebfaf2af01db81bc5b?toke......

daydaygo
2017/12/16
0
1
Laravel5.3之Decorator Pattern

说明:Laravel中Middleware的实现主要利用了Decorator Pattern的设计,本文主要先学习下Decorator Pattern如何实现,为后面学习Middleware的设计做个铺垫。Decorator Pattern和Adapter Patte...

botkenni
2016/10/27
5
0
Laravel5.3之Session源码解析(中)

说明:在上篇中学习了session的启动过程,主要分为两步,一是session的实例化,即IlluminateSessionStore的实例化;二是从session存储介质redis中读取的数据。Laravel5.3把session垃圾回收放...

botkenni
2016/11/19
12
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

NNS域名系统之域名竞拍

0x00 前言 其实在官方文档中已经对域名竞拍的过程有详细的描述,感兴趣的可以移步http://doc.neons.name/zh_CN/latest/nns_protocol.html#id30 此处查阅。 我这里主要对轻钱包开发中会用到的...

暖冰
今天
0
0
32.filter表案例 nat表应用 (iptables)

10.15 iptables filter表案例 10.16/10.17/10.18 iptables nat表应用 10.15 iptables filter表案例: ~1. 写一个具体的iptables小案例,需求是把80端口、22端口、21 端口放行。但是,22端口我...

王鑫linux
今天
0
0
shell中的函数&shell中的数组&告警系统需求分析

20.16/20.17 shell中的函数 20.18 shell中的数组 20.19 告警系统需求分析

影夜Linux
今天
0
0
Linux网络基础、Linux防火墙

Linux网络基础 ip addr 命令 :查看网口信息 ifconfig命令:查看网口信息,要比ip addr更明了一些 centos 7默认没安装ifconfig命令,可以使用yum install -y net-tools命令来安装。 ifconfig...

李超小牛子
今天
1
0
[机器学习]回归--Decision Tree Regression

CART决策树又称分类回归树,当数据集的因变量为连续性数值时,该树算法就是一个回归树,可以用叶节点观察的均值作为预测值;当数据集的因变量为离散型数值时,该树算法就是一个分类树,可以很...

wangxuwei
昨天
1
0
Redis做分布式无锁CAS的问题

因为Redis本身是单线程的,具备原子性,所以可以用来做分布式无锁的操作,但会有一点小问题。 public interface OrderService { public String getOrderNo();} public class OrderRe...

算法之名
昨天
10
0
143. Reorder List - LeetCode

Question 143. Reorder List Solution 题目大意:给一个链表,将这个列表分成前后两部分,后半部分反转,再将这两分链表的节点交替连接成一个新的链表 思路 :先将链表分成前后两部分,将后部...

yysue
昨天
1
0
数据结构与算法1

第一个代码,描述一个被称为BankAccount的类,该类模拟了银行中的账户操作。程序建立了一个开户金额,显示金额,存款,取款并显示余额。 主要的知识点联系为类的含义,构造函数,公有和私有。...

沉迷于编程的小菜菜
昨天
1
0
从为什么别的队伍总比你的快说起

在机场候检排队的时候,大多数情况下,别的队伍都要比自己所在的队伍快,并常常懊悔当初怎么没去那个队。 其实,最快的队伍只能有一个,而排队之前并不知道那个队快。所以,如果有六个队伍你...

我是菜鸟我骄傲
昨天
1
0
分布式事务常见的解决方案

随着互联网的发展,越来越多的多服务相互之间的调用,这时候就产生了一个问题,在单项目情况下很容易实现的事务控制(通过数据库的acid控制),变得不那么容易。 这时候就产生了多种方案: ...

小海bug
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部