1.1 Laravel 生命周期中的几大阶段

四海八荒,世间万物,皆是生命,生命的形态虽各有不同,但都逃不出各自物种的“劫数”,“劫数”太过于玄幻,后来就发明了一个新词儿:“周期”。万物之灵的人类参明悟透后,把生命周期归纳成最简单的两个字 “生”“命”,因何而生,命定何处,皆有命理,任他王侯将相还是大罗金仙,况 Laravel 乎?

 

Laravel 能成为目前最流行的 PHP 开发框架绝对是有它独到之处的,不然它也不会以这么快的速度燎原 PHP 编程界,学习 Laravel 的时候,如果能把它的生命周期搞清楚,那绝对比学习 Laravel 框架边边角角的小特性重要的多,官网的描述还是比较简单的,只对核心的概念和大的流程进行了简单的介绍,但即便只是个简单的流程介绍,对于理解 Laravel 来说也是非常有价值的,我也不能免这个俗,再啰嗦一遍,毕竟要为后面的内容做些铺垫工作。

 

那咱们先铺什么呢, Laravel 毕竟是 PHP 的开发框架,咱们还是先铺一铺 PHP 的生命周期,Laravel 作为 PHP 的开发框架,Laravel 的小命肯定比 PHP 的命要短一些的。我们都知道 PHP 有两种运行模式,其实不光 PHP,所有的网络编程语言都有这两种运行模式

[1] 命令行界面模式 - CLI 模式

[2] WEB 服务器模式

 

早期的 PHPer 接触 CLI 比较多一些,直接在命令行中使用 php 指令运行 PHP 文件;近些年,随着编程工具越来越先进,开发环境的部署越来越傻瓜化,编程框架越来越成熟,很多人学习 PHP 与之前老咖们大有不同,多是直接采用 WEB 服务器运行模式,用专业的 Apache ,Nginx或者其他的专业服务器软件作为宿主服务器接受网络请求然后交由 PHP 解析和运行,在这种模式下学习比过去上古时代的 PHPer 要幸福得多了去了。就像现在学习 Java 的人一样,没有几个会在命令行底下编译运行 java 程序了。但是要了解 PHP 的生命周期的话,原生态的 CLI 运行模式却是不二之选。当我们请求 PHP 进行文件处理的时候,会历经以下 5 个大的阶段的转换:

 

1.  模块初始化阶段(MINIT)

在这个阶段 PHP 首先检查 php.ini 文件中定义的扩展模块并对其进行初始化和加载工作,mysql、mbstring、json等等我们需要的功能扩展模块都会在这个阶段完成

 

2.  请求初始化阶段(RINIT)

初始化本次脚本请求所需要的变量以及变量值内容符号表,我们熟知的 $_SESSION,$_COOKIE,$GLOBAL,$_GET,$_POST 等等超全局变量都会在这个阶段完成初始化的工作 

 

3.  执行指定的 PHP 脚本程序 

 

4.  请求处理完成阶段

这是第二个阶段的逆操作,在这个阶段,完成所有请求相关变量和符号表的清理工作,如 unset($_POST),然后按顺序调用扩展模块的 RSHUTDOWN 方法,通知扩展做好关闭前的准备工作。

 

5. 模块关闭阶段

这是阶段(1)的逆操作, PHP 调用每个扩展的 MSHUTDOWN 方法释放内存  

 

PHP生命周期 

这是完整的的 PHP 处理请求的生命周期,随着专业化的服务器软件 Apache 和后来 Nginx,Tomcat 等软件的崛起,系统内部的专业分工发生了变化,人类社会的分工和协作从来都没有停止进化和演变,作为人类的智慧的产物同样随着人类思想的进步和创造力的提升一步步发生着变化,人们把现实中的变化,逐步映射到了计算机系统中。更专业的服务器软件可以更好的实现高并发,多线程,更高的稳定性和异步事件的处理能力,CLI 模式虽然很原生态,但是由于我们部署网站或者应用到服务器的时候,采用的都是 WEB 服务器模式,那咱们就应该把主要的精力放在 WEB 服务器模式的生命周期上,正好也看看专业的服务器软件为什么能够提升执行效率,实现更好的服务。

 

那 WEB 模式的生命周期有什么不同的,CLI 模式时,每次脚本执行都会经过完整的 5 个生命周期的阶段,WEB 模式下,阶段 1 和阶段 5 只会执行一次,以后的每次请求会重复 2 到 4 的生命周期阶段,因此无需每次都重复的初始化扩展模块,进而节省了系统运行资源,带来了效率的提升。至此,咱们先给 Laravel 做一个合理的定位,Laravel 生命周期只运行在第三个阶段。其实不光 Laravel 框架,只要是使用 WEB 模式对请求进行处理的,其他的 PHP 开发框架的生命周期也是在第三个阶段。

 

技术人员通常会犯两个截然相反的错误,一是把问题想得太过简单,随便拍胸脯;二就是把事情想得太复杂,畏首畏尾不敢动。在技术领域,或者说现实社会中,问题虽然各有不同,但是解决问题的方式方法却都秉着 “如有雷同,纯属巧合” 的理念彼此借鉴和学习,技术领域的很多解决方案都可以在现实中找到他们存在的影子。之所以先说一说 PHP 的生命周期,也是为了让读者更好的理解开发框架是怎么一回事,所有框架设计的处理流程,跟人们在现实中处理任何一个任务的流程也都差不多,无非就是根据任务需要做准备(准备人力,物力,财力,时间),根据任务做资源整合;然后把任务进行分解并分配资源,解决问题,搞定任务,最后解散,当然解散前,提前也要告知大家一下不是。

 

PHP 的生命周期,每一次请求结束后,PHP 的变量都会销毁(unset),所以说虽然 Laravel 是单例运行的,但是这个单例的 Laravel 实例依旧很短命,我们在 Laravel 中使用的静态变量也只在当前请求过程中有效,不能被多个请求共享,请求一旦结束,变量的尊贵地位也会立即被废(在请求处理完成阶段销毁)。知道了这些之后,我们就能更好的理解所有的 PHP 开发框架的处理请求的流程,以及数据的生命周期。PHP 是一种脚本语言,所有的变量只在一次请求中有效,下一次新的请求过来之后,所有的变量都已物是人非。所以当我们说 PHP 的生命周期的时候,通常都会加上一个限定词 “单次请求”, 全名就是PHP在单次网络请求中的生命周期 ~ 

 

OK,现在我们跟随一个 “请求” 进入到 Laravel 内部,看看在 Laravel 框架内部,它将经历什么样的磨难,能否取得“大乘佛法三藏真经”。这个请求首先会进入 public\index.php 入口文件,所有的网络请求都会从这里进入,就像大家学习编程语言时接触的 main()  函数一样。 

Laravel 生命周期

 1.使用Composer的自动加载功能,把所有需要使用的 PHP 文件添加到系统中以备调用
require __DIR__.'/../vendor/autoload.php';

2.创建 Laravel 单例应用实例
$app = require_once __DIR__.'/../bootstrap/app.php';

3.最关键的步骤,接受请求,对请求进行处理,返回请求处理的结果
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
$response = $kernel->handle(
$request = Illuminate\Http\Request::capture()
);
$response->send();

4.请求结束,进行回调
$kernel->terminate($request, $response);

至此,我们虽然没有从细节代码上看到 Laravel 开发框架都做了什么,咱们只是在高空纵览了一下全景,但是这些工作还是很有必要的,对于更深入的理解所有的 PHP 开发框架都有一些帮助,TP 曾是国内最受欢迎的 PHP 开发框架,但是它最新的版本很多东西跟 Laravel 也是越来越像,好的实践和方法谁有不喜欢呢。之前写别的东西我的风格还是很轻浮的,但是写 Laravel 生命周期,尤其一涉及到代码和逻辑思考,想浪也浪不起来,但是这也是我喜欢写代码的一个重要原因,它能让人安静下来,在这个浮躁的社会中,难得一方宁静地了~