这是一个创建于 2017-08-10 23:04:50 的文章,其中的信息可能已经有所发展或是发生改变。

世间万物皆有生命周期,当我们使用任何工具时都需要理解它的工作原理,那么用起来就会得心应手,应用开发也是如此。理解了它的原理,那么使用起来就会游刃有余。
在了解 Laravel 的生命周期前,我们先回顾一下PHP 的生命周期。

PHP 的生命周期

PHP 的运行模式

PHP两种运行模式是WEB模式、CLI模式。

  1. 当我们在终端敲入php这个命令的时候,使用的是CLI模式。
  2. 当使用Nginx或者别web服务器作为宿主处理一个到来的请求时,使用的是WEB模式。

生命周期

当我们请求一个php文件时,PHP 为了完成这次请求,会发生5个阶段的生命周期切换:

  1. 模块初始化(MINIT),即调用 php.ini 中指明的扩展的初始化函数进行初始化工作,如 mysql 扩展。

  2. 请求初始化(RINIT),即初始化为执行本次脚本所需要的变量名称和变量值内容的符号表,如 $_SESSION变量。

  3. 执行该PHP脚本。

  4. 请求处理完成(Request Shutdown),按顺序调用各个模块的 RSHUTDOWN 方法,对每个变量调用 unset函数,如 unset $_SESSION 变量。

  5. 关闭模块(Module Shutdown) , PHP调用每个扩展的 MSHUTDOWN 方法,这是各个模块最后一次释放内存的机会。这意味着没有下一个请求了。

WEB模式和CLI(命令行)模式很相似,区别是:

  1. CLI 模式会在每次脚本执行经历完整的5个周期,因为你脚本执行完不会有下一个请求;
  2. WEB模式为了应对并发,可能采用多线程,因此生命周期15有可能只执行一次,下次请求到来时重复2-4的生命周期,这样就节省了系统模块初始化所带来的开销。

可以看出PHP生命周期是很对称的。说了这么多,就是为了定位Laravel运行在哪里,没错,Laravel仅仅运行再 第三个阶段:

PHP生命周期

作用

理解这些,你就可以优化你的 Laravel 代码,可以更加深入的了解 Laravel 的singleton(单例)。至少你知道了,每一次请求结束,PHP 的变量都会 unset,Laravel 的 singleton 只是在某一次请求过程中的singleton;你在 Laravel 中的静态变量也不能在多个请求之间共享,因为每一次请求结束都会 unset。理解这些概念,是写高质量代码的第一步,也是最关键的一步。因此记住,PHP是一种脚本语言,所有的变量只会在这一次请求中生效,下次请求之时已被重置,而不像Java静态变量拥有全局作用。

Laravel 的生命周期

概述

Laravel 的生命周期从public\index.php开始,从public\index.php结束。

请求过程

下面是 public\index.php的全部源码,更具体来说可以分为四步:

1. require __DIR__.'/../bootstrap/autoload.php';2. $app = require_once __DIR__.'/../bootstrap/app.php';$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);3. $response = $kernel->handle($request = Illuminate\Http\Request::capture());$response->send();4. $kernel->terminate($request, $response);

以下是四步详细的解释是:
composer自动加载需要的类

  1. 文件载入composer生成的自动加载设置,包括所有你 composer require的依赖。

  2. 生成容器Container,Application实例,并向容器注册核心组件(HttpKernel,ConsoleKernel ,ExceptionHandler)(对应代码2,容器很重要,后面详细讲解)。

  3. 处理请求,生成并发送响应(对应代码3,毫不夸张的说,你99%的代码都运行在这个小小的handle 方法里面)。

  4. 请求结束,进行回调(对应代码4,还记得可终止中间件吗?没错,就是在这里回调的)。

Laravel 的请求步骤

我们不妨在详细一点:

第一步:注册加载composer自动生成的class loader

就是加载初始化第三方依赖。

第二步:生成容器 Container

并向容器注册核心组件,是从 bootstrap/app.php 脚本获取 Laravel 应用实例,

第三步:这一步是重点,处理请求,并生成发送响应。

请求被发送到 HTTP 内核或 Console 内核,这取决于进入应用的请求类型。

取决于是通过浏览器请求还是通过控制台请求。这里我们主要是通过浏览器请求。

HTTP 内核继承自 Illuminate\Foundation\Http\Kernel 类,该类定义了一个 bootstrappers 数组,这个数组中的类在请求被执行前运行,这些 bootstrappers 配置了错误处理、日志、检测应用环境以及其它在请求被处理前需要执行的任务。

protected $bootstrappers = [//注册系统环境配置 (.env)'Illuminate\Foundation\Bootstrap\DetectEnvironment',//注册系统配置(config)'Illuminate\Foundation\Bootstrap\LoadConfiguration',//注册日志配置'Illuminate\Foundation\Bootstrap\ConfigureLogging',//注册异常处理'Illuminate\Foundation\Bootstrap\HandleExceptions',//注册服务容器的门面,Facade 是个提供从容器访问对象的类。'Illuminate\Foundation\Bootstrap\RegisterFacades',//注册服务提供者'Illuminate\Foundation\Bootstrap\RegisterProviders',//注册服务提供者 `boot`'Illuminate\Foundation\Bootstrap\BootProviders',];

注意顺序:
Facades 先于ServiceProvidersFacades也是重点,后面说,这里简单提一下,注册 Facades 就是注册 config\app.php中的aliases 数组,你使用的很多类,如AuthCache,DB等等都是Facades;而ServiceProvidersregister方法永远先于boot方法执行,以免产生boot方法依赖某个实例而该实例还未注册的现象。

HTTP 内核还定义了一系列所有请求在处理前需要经过的 HTTP 中间件,这些中间件处理 HTTP 会话的读写、判断应用是否处于维护模式、验证 CSRF 令牌等等。

HTTP 内核的标志性方法 handle处理的逻辑相当简单:获取一个 Request,返回一个 Response,把该内核想象作一个代表整个应用的大黑盒子,输入 HTTP 请求,返回 HTTP 响应。

第四步:将请求传递给路由。

在Laravel基础的服务启动之后,就要把请求传递给路由了。路由器将会分发请求到路由或控制器,同时运行所有路由指定的中间件。

传递给路由是通过 Pipeline(管道)来传递的,但是Pipeline有一堵墙,在传递给路由之前所有请求都要经过,这堵墙定义在app\Http\Kernel.php中的$middleware数组中,没错就是中间件,默认只有一个CheckForMaintenanceMode中间件,用来检测你的网站是否暂时关闭。这是一个全局中间件,所有请求都要经过,你也可以添加自己的全局中间件。

然后遍历所有注册的路由,找到最先符合的第一个路由,经过它的路由中间件,进入到控制器或者闭包函数,执行你的具体逻辑代码。

所以,当请求到达你写的代码之前,Laravel已经做了大量工作,请求也经过了千难万险,那些不符合或者恶意的的请求已被Laravel隔离在外。

处理请求到响应过程

作者:伊Summer
链接:https://www.jianshu.com/p/08b810b720d9
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

Laravel 的生命周期相关推荐

  1. 图解 Laravel 请求的完整生命周期

    来源 | CSDN博客精选 头图 | 视觉中国 世间万物皆有生命周期,当我们使用任何工具时都需要理解它的工作原理,那么用起来就会得心应手,应用开发也是如此.理解了它的原理,那么使用起来就会游刃有余. ...

  2. 深度挖掘 Laravel 生命周期

    本文首发于个人博客 深度挖掘 Laravel 生命周期,转载请注明出处. 这篇文章我们来聊聊 「Laravel 生命周期」 这个主题.虽然网络上已经有很多关于这个主题的探讨,但这个主题依然值得我们去研 ...

  3. laravel进阶学习之laravel生命周期

    Laravel 生命周期概括起来大致可分为三步 1.加载依赖 2.创建 Laravel 应用实例 3.接收请求并响应 加载依赖及生成实例部分 一个请求进来之后由public/index.php开始也由 ...

  4. 关于Vue实例的生命周期created和mounted的区别

    关于作者 程序开发人员,不拘泥于语言与技术,目前主要从事PHP和前端开发,使用Laravel和VueJs,App端使用Apicloud混合式开发.合适和够用是最完美的追求. 个人网站:http://w ...

  5. LTV 即用户生命周期价值

    20220321 https://mp.weixin.qq.com/s/kPoojfRCbvCCV4zpnCimmQ 指标计算详细介绍 数据分析|如何做好用户生命周期价值分析 LTV https:// ...

  6. Harmony生命周期

    Harmony生命周期 系统管理或用户操作等行为,均会引起Page实例在其生命周期的不同状态之间进行转换.Ability类提供的回调机制能够让Page及时感知外界变化,从而正确地应对状态变化(比如释放 ...

  7. Activity在有Dialog时按Home键的生命周期

    当一个Activity弹出Dialog对话框时,程序的生命周期依然是onCreate() - onStart() - onResume(),在弹出Dialog的时候并没有onPause()和onSto ...

  8. 横竖屏切换时Activity的生命周期

    1.不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏执行一次,切竖屏执行两次. 2.设置Activity的android:configChang ...

  9. Android中Service生命周期、启动、绑定、混合使用

    一.Activity和Service如何绑定: 1.Service和Activity之间的连接可以用ServiceConnection来实现.实现一个ServiceConnection对象实例,重写o ...

最新文章

  1. Hadoop集群搭建(七:MySQL的安装配置)
  2. 2018-2019-1 20189221 《深入理解计算机系统》第 1 周学习总结
  3. python区块链框架_20分钟,我用Python实现区块链架构!
  4. (2,1,3)卷积码与一种QC-LDPC码的译码性能对比
  5. io字符流和字节流之间的转换和基本应用练习
  6. 插件开发之360 DroidPlugin源码分析(三)Binder代理
  7. Datasqueeze v2.0.7
  8. java必记单词_70个学习JAVA必背的英语单词,了解下
  9. pyserial查看串口
  10. 耗时两周,纯手敲python入门级基础笔记
  11. ZZULIOJ 1919 D
  12. gtx1060+linux+双显卡,ubuntu14.04+GTX1060 重新安装显卡驱动
  13. Human-in-the-Loop Optimization of Exoskeleton Assistance Via Online Simulation of Metabolic Cost
  14. 【报告分享】2021年小红书kol营销白皮-千瓜数据(附下载)
  15. VSCode+Marp:用Markdown做幻灯片(进阶篇)-宋森安
  16. Deep Learning_main
  17. 数据库 流量切分_一种基于flex的可视化多层流量切分界面的实现
  18. C++到底还能做什么?
  19. PowerBulider create database
  20. 高并发编程之生产者—消费者设计模式

热门文章

  1. springboot高校学习资源共享系统java
  2. IF:4+ 鉴定与股骨头坏死软骨氧化应激相关的Hub基因和通路
  3. 山外多功能调试助手用作MM32虚拟示波器
  4. PPT转换成PDF转换软件教程
  5. 【第十七届智能车】智能车图像处理(2)-赛道边界的简单提取和无元素循迹
  6. Jackson:Cannot construct instance of **** (although at least one Creator exists):
  7. windows+qtcreator5+opencv3.4配置(成功且包含解释和各类错误)
  8. matlab中sparse和full函数的使用
  9. js实现鼠标点击自动选中点击元素内的文字
  10. 服务器磁盘满了 处理过程