Laravel框架的入口文件public/index.php

<?php/*** Laravel - A PHP Framework For Web Artisans** @package  Laravel* @author   Taylor Otwell <taylor@laravel.com>*/define('LARAVEL_START', microtime(true));/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader for
| our application. We just need to utilize it! We'll simply require it
| into the script here so that we don't have to worry about manual
| loading any of our classes later on. It feels great to relax.
|
*/require __DIR__.'/../vendor/autoload.php';/*
|--------------------------------------------------------------------------
| Turn On The Lights
|--------------------------------------------------------------------------
|
| We need to illuminate PHP development, so let us turn on the lights.
| This bootstraps the framework and gets it ready for use, then it
| will load up this application so that we can run it and send
| the responses back to the browser and delight our users.
|
*/$app = require_once __DIR__.'/../bootstrap/app.php';/*
|--------------------------------------------------------------------------
| Run The Application
|--------------------------------------------------------------------------
|
| Once we have the application, we can handle the incoming request
| through the kernel, and send the associated response back to
| the client's browser allowing them to enjoy the creative
| and wonderful application we have prepared for them.
|
*/$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);$response = $kernel->handle($request = Illuminate\Http\Request::capture()
);$response->send();$kernel->terminate($request, $response);

根据作者的注释可以知道这几行代码的作用:

  1. 定义常量记录框架启动时间。
  2. 加载composer包管理器中的自动加载器到当前命名空间(根命名空间)。
  3. 获取一个Application类的实例$app,这个实例继承了Container类,并且作为一个服务容器承担连接各种服务的功能,我们可以从这个容器获取各种服务,如日志、数据库、缓存、事件等。
  4. 调用$app的make方法获取一个kernel类,用kernel类处理请求对象(Request类的实例,包含了请求信息),之后返回一个$response来发送响应,最后调用$kernel的terminate方法结束本次请求,这样,一个完整的http请求就完成了。

框架的启动过程在kernel调用handle方法时进行,那么启动框架到底做了什么事情?这就要深入了解下kernel类的handle方法了。
找到kernel类文件中的handle 方法:

/*** Handle an incoming HTTP request.** @param  \Illuminate\Http\Request  $request* @return \Illuminate\Http\Response*/public function handle($request){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);}$this->app['events']->dispatch(new Events\RequestHandled($request, $response));return $response;}

这个方法接受一个\Illuminate\Http\Request请求类实例作为参数,然后返回一个\Illuminate\Http\Response响应类。正常请求会调用sendRequestThroughRouter方法,翻过过来就是:“将请求送往路由”,然后返回响应,如果产生异常则调用异常处理方法,将异常信息包装为响应类。接下来看下sendRequestThroughRouter方法:

/*** Send the given request through the middleware / router.** @param  \Illuminate\Http\Request  $request* @return \Illuminate\Http\Response*/protected function sendRequestThroughRouter($request){$this->app->instance('request', $request);Facade::clearResolvedInstance('request');$this->bootstrap();return (new Pipeline($this->app))->send($request)->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)->then($this->dispatchToRouter());}

这个方法并不长,只有四行代码:

  1. 调用服务容器的instance方法绑定一个request实例
  2. 调用Illuminate\Support\Facades\Facade类(门面类基类)的clearResolvedInstance静态方法清除resolvedInstance属性(已解析实例)中的’request’实体。
  3. 调用bootstrap方法启动框架。
  4. new一个管道类,依次调用send、through、then方法使请求通过中间件,最后分发到路由类处理。

看到这里,就知道框架的启动过程放在了bootstrap方法,继续看下这个方法:

/*** Bootstrap the application for HTTP requests.** @return void*/public function bootstrap(){if (! $this->app->hasBeenBootstrapped()) {$this->app->bootstrapWith($this->bootstrappers());}}

判断框架是否启动,未启动则调用服务容器的bootstrapWith方法,传入了kernel的bootstrappers 属性,这个属性是一个数组,数组的键值是类名,这些是在框架启动之时需要注入的类,如管理环境变量、框架配置的类,处理异常类,注册门面类,启动服务类。

protected $bootstrappers = [\Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables::class,\Illuminate\Foundation\Bootstrap\LoadConfiguration::class,\Illuminate\Foundation\Bootstrap\HandleExceptions::class,\Illuminate\Foundation\Bootstrap\RegisterFacades::class,\Illuminate\Foundation\Bootstrap\RegisterProviders::class,\Illuminate\Foundation\Bootstrap\BootProviders::class,];

继续看下服务容器的bootstrapWith方法:

/*** Run the given array of bootstrap classes.** @param  string[]  $bootstrappers* @return void*/public function bootstrapWith(array $bootstrappers){$this->hasBeenBootstrapped = true;foreach ($bootstrappers as $bootstrapper) {$this['events']->dispatch('bootstrapping: '.$bootstrapper, [$this]);$this->make($bootstrapper)->bootstrap($this);$this['events']->dispatch('bootstrapped: '.$bootstrapper, [$this]);}}

在这个方法中只有几行代码,将启动属性修改为已启动,然后遍历bootstrappers 数组,启动框架的过程就是一个加载基础类的过程:发布启动事件,调用make方法实例化基础类然后调用基础类的bootstrap方法,然后发布完成启动事件。bootstrappers 数组中的类都定义在laravel源码包 的Foundation目录的子目录Bootstrap中。这些类的功能:

  1. 加载环境变量
  2. 加载配置文件
  3. 加载异常处理类
  4. 注册门面类
  5. 注册服务提供类
  6. 启动服务类

以上就是laravel框架的启动全过程,我们在框架启动之后,还未处理请求之前调用一下框架的辅助函数dd()和app()来打印下服务容器对象:

protected function sendRequestThroughRouter($request){$this->app->instance('request', $request);Facade::clearResolvedInstance('request');$this->bootstrap();
dd(app());return (new Pipeline($this->app))->send($request)->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)->then($this->dispatchToRouter());}

打印结果:

Application {#2 ▼#basePath: "/vagrant/www/laravel5.8"#hasBeenBootstrapped: true#booted: true#bootingCallbacks: array:1 [▶]#bootedCallbacks: array:1 [▶]#terminatingCallbacks: []#serviceProviders: array:22 [▶]#loadedProviders: array:22 [▶]#deferredServices: array:102 [▶]#appPath: null#databasePath: null#storagePath: null#environmentPath: null#environmentFile: ".env"#namespace: null#resolved: array:20 [▶]#bindings: array:41 [▶]#methodBindings: []#instances: array:26 [▼"path" => "/vagrant/www/laravel5.8/app""path.base" => "/vagrant/www/laravel5.8""path.lang" => "/vagrant/www/laravel5.8/resources/lang""path.config" => "/vagrant/www/laravel5.8/config""path.public" => "/vagrant/www/laravel5.8/public""path.storage" => "/vagrant/www/laravel5.8/storage""path.database" => "/vagrant/www/laravel5.8/database""path.resources" => "/vagrant/www/laravel5.8/resources""path.bootstrap" => "/vagrant/www/laravel5.8/bootstrap""app" => Application {#2}"Illuminate\Container\Container" => Application {#2}"Illuminate\Foundation\PackageManifest" => PackageManifest {#5 ▶}"events" => Dispatcher {#27 ▶}"router" => Router {#26 ▶}"Illuminate\Contracts\Http\Kernel" => Kernel {#30 ▶}"request" => Request {#43 ▶}"config" => Repository {#34 ▶}"db.factory" => ConnectionFactory {#53 ▶}"db" => DatabaseManager {#37 ▶}"view.engine.resolver" => EngineResolver {#105 ▶}"files" => Filesystem {#111}"view" => Factory {#112 ▶}"translation.loader" => FileLoader {#119 ▶}"translator" => Translator {#120 ▶}"routes" => RouteCollection {#29 ▶}"url" => UrlGenerator {#128 ▶}]#aliases: array:66 [▶]#abstractAliases: array:36 [▶]#extenders: []#tags: []#buildStack: []#with: []+contextual: array:1 [▶]#reboundCallbacks: array:2 [▶]#globalResolvingCallbacks: []#globalAfterResolvingCallbacks: []#resolvingCallbacks: array:1 [▶]#afterResolvingCallbacks: array:1 [▶]
}

可以看到在处理请求之前,服务容器中的instances共享实例属性,就已经注册了十几个对象,而在处理请求的过程中又还要注册很多对象,这也就不难理解为什么laravel框架的并发性较差了。

Laravel框架的运行过程相关推荐

  1. php larval框架运行环境,Laravel框架的运行环境配置(一)

    Laravel框架 学习参考: Laravel的特点; 单一入口:所有请求必须从单入口开始,主要是关于管理[统一的参数过滤] MVC的思想 ORM操作数据库 一个模型对应数据库里面的一张表,对象的属性 ...

  2. laravel框架实践1

    一.Laravel简介 Laravel是一套简洁,优雅的PHPWeb开发框架 具有富于表达性且简洁的语法 Laravel是易于理解且强大的,它提供了强大的工具用以开发大型,健壮的应用. 具有验证.路由 ...

  3. Laravel框架的简介、安装以及启动。

    一.Laravel简介 Laravel是一套简洁,优雅的PHP Web开发框架 具有富于表达性且简洁的语法 Laravel是易于理解且强大的,它提供了强大的工具用以开发大型,健壮的应用. 具有验证.路 ...

  4. 关于laravel框架中and 和orWhere 的多条件嵌套

    最近的项目一直在使用laravel框架,在使用过程中突然发现自带的助手函数where()与orWhere()使用起来和自己预想中的不一样,特此记录学习防止以后忘记. 举个例子我们需要查找状态为1,名称 ...

  5. 【Laravel框架】简介

    目录 导语 一.简介 二.开发环境配置与要求 三.PHP的注意事项 Laravel 简介 导语 Laravel是一套简洁,优雅的PHPWeb开发框架,具有富于表达性且简洁的语法 Laravel是易于理 ...

  6. php框架laravel原理,Laravel框架运行原理

    写在前面: 使用任何框架,如果理解该框架原理,应用起来会更加得心应手. 一.生命周期 1. 入口文件: Laravel框架所有请求入口统一进入/public/index.php文件,请求通过Ngxin ...

  7. 关于laravel 框架运行数据库迁移文件的一个小坑以及常用php artisan命令

    小白我因为最近开发的一系列项目都是用的laravel框架,所以为了方便有时候就会直接复制一份代码以此作为新项目的基础.可能因为"因为夜路走多了,所以掉坑里了">>> ...

  8. php larval框架运行环境,4种Windows系统下Laravel框架的开发环境安装及部署方法详解...

    1.准备工作 1.1PHP集成环境 这里我们使用的是XAMPP,XAMPP是一个功能强大的建站集成软件包,采用一键安装的方式,包含PHP7.0.Mysql.Tomcat等.最新版下载地址:PHP 5. ...

  9. php runtimeexception,Laravel框架运行出错提示RuntimeException No application encryption...

    关于Laravel,出错提示,RuntimeException,No,application,encryption,key,has,been,specified.,解决方法,Laravel框架运行出错 ...

  10. Laravel框架一:原理机制篇

    转载自http://www.cnblogs.com/XiongMaoMengNan/p/6644892.html Laravel作为在国内国外都颇为流行的PHP框架,风格优雅,其拥有自己的一些特点. ...

最新文章

  1. visio二次开发___事件篇___事件分类
  2. webpack增量打包多页应用
  3. 《研磨设计模式》chap15 组合模式(2)改写示例+总结
  4. 手把手带你复现ICCV 2017经典论文—PyraNet
  5. 【ArcGIS遇上Python】ArcGIS Python按照指定字段批量筛选不同类型的图斑(以土地利用数据为例)
  6. P3889-[GDOI2014]吃【线段树】
  7. [react] react16的reconciliation和commit分别是什么?
  8. 2018 Machine Learning
  9. pat乙级相当于什么水平_英语四六级/专四/专八相当于美国人什么水平?
  10. PacMan开发-碰撞检测实现
  11. InnoDB存储引擎MVCC的工作原理
  12. 导师说,再招女生,他就是孙子
  13. 伺服驱动器--增益调整
  14. java编程基本基本框架_盘点Java编程中常用的框架
  15. 基于拦截器实现防表单重复提交
  16. 类似京东商城客户端应用iOS源码
  17. 数值分析matlab最小二乘法,数值分析 最小二乘 matlab
  18. 程序员去外包的后遗症是什么
  19. 奥维地图怎么标注文字_如何在奥维地图上准确地告诉别人“我在哪?”
  20. DTOJ 4745. 进制转换

热门文章

  1. 都2022了,我为什么还要写博客?
  2. mysql8 错误日志_MySQL 8 服务器日志
  3. 计算机网络总复习题(含答案)
  4. python代码控制机械臂_Dobot 机械臂
  5. 移动计算的未来:是什么在推动变革? | 幂集创新
  6. ant安装配置使用介绍及eclipse中使用
  7. Cisco VPP fib.h中文对照
  8. java 传智播客 毕向东_传智播客,毕向东Java详细基础教程下载
  9. 常用元器件使用方法4:一种Micro-SIM卡连接器的使用方法
  10. hash算法_Win10_64 默认应用的UserChoice Hash算法学习