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 生命周期,尤其一涉及到代码和逻辑思考,想浪也浪不起来,但是这也是我喜欢写代码的一个重要原因,它能让人安静下来,在这个浮躁的社会中,难得一方宁静地了~

评论区
西门撸码 2018.10.24 07:45

我把一楼全站了,支持站长的这个专题系列

国营 2018.10.24 07:48

朋友,可别这么玩,咱们以交流技术为主,不玩儿抢楼层的游戏

哈哈鬼王萧玉 2020.12.04 01:38

加油干!

‭‭小铭 2018.10.30 10:19

我要宣传本站,这么好的网站,人员有点儿稀少。

国营 2018.10.30 11:13

谢谢肯定,去年北京冬天流感在家养病才开始做的这个网站,也没推广过,人员稀少挺正常的,但高兴的是来过的朋友都陪着这个网站走了现在。

jejezhang 2018.11.22 01:11

手机观看某些字符会超出

国营 2018.11.22 01:46

这个可以无视它,手机浏览器太多了,对标准的支持质量也有高有低,代码部分超出了,可以用手拖动那部分看,coding10主要还是建议大家用pc看,有个更好的学习环境

轮子 2018.11.24 06:33

很喜欢,谢谢作者

国营 2018.11.24 06:34

不客气,打开左边目录小桌板,还有内容

轮子 2018.11.24 06:36

我决定把所有的内容从头到尾看一遍~

郝合心 2018.11.28 07:13

当前解散前 还是 当然解放前 呢?

国营 2018.11.28 07:14

我的错,是当然解放前,谢谢你这么认真

郝合心 2018.11.28 07:31

当然解散前,哈哈

国营 2018.11.28 07:35

网页左侧有个目录按钮,可以展开看图书里其他的内容,我把这个目录做的太隐蔽了

伊泽 2018.11.28 12:45

网站页面太宽了,强烈建议修改模板!!!

国营 2018.11.29 15:20

再次感谢你的建议,我觉得特别好

Oscar 2018.11.29 05:29

写的很好!1024

国营 2018.11.29 07:39

这是一个技术人应有的职业素质

Tiana 2018.11.29 07:56

慢慢跟着大佬学习

国营 2018.11.29 07:58

共同努力,你的头像默认分配了 GEEK 那你就朝着极客奔跑吧

Benny 2018.12.02 05:52

感谢站主的分享 👍

国营 2018.12.02 06:27

不客气

bobozhou 2018.12.02 13:10

学习php2个月接触larave3周了,正需要这些基础概念性的知识,去帮助自己更好的理解laravel,谢谢站长了!

国营 2018.12.02 13:12

刚开始很多都是倒在各种概念上了,踏过去也就没事了

xxx 2018.12.03 03:52

大佬,我觉得的这个留言回复的风格有点丑,最后的回复消息都挤到右侧了.

国营 2018.12.03 04:10

呵呵,这种风格确实有这个缺点,评论多了之后会出现挤压

bigliang 2018.12.03 09:34

想咨询站长,页面的设计也是自己完成的吗。想做一个自己的网站,页面怎么布局无从下手。

国营 2018.12.03 09:41

用的 bootstrap 搭建的网站页面。你要做的话首先把你网站想要的功能都列举出来,然后排优先级,再就是把功能的展现方式定好设计思路,剩下的就是实现了,不要一开始总想着界面啥样,页面是服务于你的业务的,只要能把业务服务好,界面UI好看不好看,特效多不多不那么重要

bigliang 2018.12.04 00:06

感谢站长的回复,受益匪浅。那我就先从功能开始了。

国营 2018.12.04 01:37

不客气,你遇到的问题很多人和盲目创业者经常遇见,把太多精力和重点放在了页面和交互上,可是UI以及UI的交互是基于业务的,应该先把业务以及业务流程梳理清楚才对,结果太多人做产品的时候搞错了轻重,屁股指挥脑袋,本末倒置了;另一个常犯的错误就是,只关注了客户端,没有思考一个产品背后的支撑系统,没有把运营运维考虑到,做出的东西只是样子货,没有真正跟公司的业务结合起来,这也是大部分项目会失败的一个重要原因。后台支撑体系的建设优先级也是高于客户端建设的,不是靠简单的一个app或网站就能改变的。

anton gao 2018.12.04 12:27

写的很好,静下来,好好学点东西

国营 2018.12.04 12:30

宁静致远嘛

pepsi 2018.12.05 02:26

发现了新大陆, 哈哈

国营 2018.12.05 02:28

不新了,都一年的老土地了

carey 2018.12.06 06:15

支持大佬, 正是自己目前所需要理解的部分。 手动抱拳了。

国营 2018.12.06 06:28

不客气,相互促进

古树乡音 2018.12.11 08:36

为什么我注册“古树乡音”这个账号时跳转到whoops,looks like something went wrong这个页面,但是我返回网站后注册是成功的,能登陆,我又换火狐测试了一个“测试bug”注册,没问题,这个“测试bug”账号可以删掉哦

国营 2018.12.11 08:49

哈哈,因为你中奖了,刚好赶上腾讯邮件系统出问题

feivorid 2018.12.18 06:32

很赞

cchealther 2018.12.22 01:29

谢谢大佬

ln8198 2018.12.26 06:31

过来支持下

国营 2018.12.26 07:07

那就多来捧场吧

anyux 2018.12.28 03:07

支持一下,嘻嘻

国营 2018.12.28 07:51

我现在最需要金钱的支持,^_^,开个玩笑

ghdlk 2019.01.31 10:44

随着专业化的服务器软件 Apache 和后来 Nginx,Tom Cat 等软件的崛起。 其中 `Tom Cat` 应该存在中间的空格么?求告知!希望不是手误打错了(可能是输入法的锅)。

国营 2019.01.31 11:14

这当然是我的锅,怎么能甩给输入法,可惜电脑带回家了,没带电源,只能手机上改了

ghdlk 2019.01.31 16:19

哈哈哈哈,因为猫和老鼠动画片里的猫叫汤姆,所以可能是输入法自动匹配名词了。

Leo 2019.02.23 14:35

感谢作者的无私分享,好网站!

国营 2019.02.23 14:39

不无私,我的网站里付费内容也是有的,也曾经全站免费了一年,后来撑不住了开始收费了

Leo 2019.02.23 14:42

人之常情,要吃饭的嘛! 小弟最近在面试换工作,专门看了你上传关于laravel理论的视频,等到换工作成功了,给你充点电费。

国营 2019.02.23 15:16

好好准备吧,预祝你找到满意的工作

123 2019.03.11 07:46

评论我

国营 2019.03.11 07:48

兄弟,别玩了,好好学习,天天尿炕 ~

goods 2019.03.15 06:28

文章底部怎么能少了分享按钮呢

国营 2019.03.15 06:37

因为这个功能低频到令人发指,所以我就没必要自恋,也不浪费时间做分享的按钮了

weave 2019.04.11 15:46

超级赞的一个网站~

lululu 2019.06.04 01:07

作者的每一篇文章写的都非常的透彻,深入浅出,精彩绝伦。。

视频每一节,都有一个让人眼前一亮的配图,质量也是秒杀掉市面上所有的视频。敬佩!

国营 2019.06.04 01:14

毕竟是自己的网站,如果自己态度都不端正、做事都不认真,那就说不过去了,也没办法获得别人的信任和尊重

国营 2019.06.04 02:24

现在越来越多人都想搞投机,愿意踏踏实实做事的人越来越少,人和人之间的信任关系越来越差了,这个网站我用这种方式搞了一年半了,坚持到现在,我觉得算是值得我骄傲的一件事

Galois 2019.06.07 09:11

你必须骄傲,现在的人,游手好闲的多,专注坚持的少

国营 2019.06.07 09:49

谢谢,做成了我骄傲一下,做不成我无悔

sundy 2019.06.27 02:40

我是在b站发现的站长,觉得讲的东西太好啦,已经买了一个专题,后续还会买,如果初期会员你能打打折我会毫不犹豫办个终身会员,哈哈😄,加油

国营 2019.06.27 03:08

呃,谢谢朋友的认可,其实我最近再考虑提升永久会员的标价,因为之前内容不多,永久会员的价格我定的低了,所以现在轮到你犹豫了,哈哈,反将一军,除了一个经济不太好的学生我优惠过,我没有优惠过任何一个人,该公平的一定要公平,不然伤害之前的用户,我宁可不赚这份钱,也不能坏了江湖规矩,还望理解~

manbofish 2019.10.12 02:26

感谢作者的无私分享,好网站!

国营 2019.10.12 02:29

哈哈,谢谢支持,有无私的也有收费的,不过我也曾全站所有资源都免费过,后来网站开销越来越大养不起就开始收费了

mengge 2019.11.06 12:44

写的真好,学习了,加油,一起加油,你加油写,我加油学

国营 2019.11.06 12:51

哈哈,我努力

wangshuangfeng 2020.02.11 09:43

"而就是把事情想得太复杂" 这里的而应该是"二"吧

国营 2020.02.11 10:22

兄弟说得对,我这次没二好

strong 2020.03.01 11:21

老师好,我看了好些视频,我都觉得声音太小了,我把电脑的声音都调到最大了,还是听不怎么清楚,只有把音箱放在耳朵边才行,不知道是不是我自己的原因,我也不知道在哪里反馈,就在这里评论了。

国营 2020.03.01 11:28

叫我站长就行了,我不是啥老师,那肯定是你电脑的原因了,两年了,说声音小的,你是第一个。有了问题哪里反馈都行,都没关系的。

yang 2020.04.20 01:25

《 定位 》

老哥,你的这个书,蛮期待的,

我来催催,哈哈哈,开个玩笑

yang 2020.04.20 01:26

111

marvin 2020.04.26 09:58

我是从ASP开发转过来的,不知道现在还有没有ASPer,哈哈

boris 2020.07.19 03:43

感謝站長

国营 2020.07.19 04:29

不客气,共同进步吧

wjim 2020.08.14 05:59

站长能增加一个回到顶部的按钮吗?

国营 2020.08.14 06:14

回到顶部太难了,我不会做,😄。帮大家活动活动手指吧,生命在于咕扭!

哈哈鬼王萧玉 2020.12.04 01:37

很不错的站点,给人耳目一新的感觉,同时干货满满。顶!

国营 2020.12.04 02:11

哈哈,欢迎新朋友,我是站长 codinget, 如果网站能帮助到你,也欢迎常来做客。虽然网站很小,但也一直在用心做。

along 2021.07.15 14:20

你好,看到这篇文章,想起来了最近在工作中的一件事情.

在项目中,需要通过API来连接另外一个服务器A,然后从A中下载为JSON的数据,因为A服务器中的数据格式和我们这边不符,还要根据数据的格式,转换成我们想要的格式,譬如,去除邮编中的破折号,把一些通用文字信息转换成数据库中的ID.接着链接数据库,写入数据.

A的数据大概有10万,我是这样设计的,每次从A中只读取100条信息,然后转换格式,写数据库,写入成功,然后在读取101到200的数据,一直循环到结束.

在写入数据库时,不只写入一张表,还要写入关联的数据表,有5个左右.所以我使用的是laravel的eloquent,先写主表,然后在依次写入关联表。

使用了transaction,100条数据commit一次

看似一切都很正常,正真运行时,奇怪的事情出现了,数据写道25000条左右时,会出现内存不够用。。。

使用php的自带函数memory_get_usage()来测试内存的使用,发现在插入循环时,内存的使用是直线上升的,100条数据插入完毕后,会占用7MB的内存。然后内存一直增加,直到不够用,强行终止。。。。

disenableQueryLog,停止使用debuggar。统统不起作用,循环结束后,把一些函数设置为null,也没有任何作用。。。

看到这篇文章,我想是不是因为我php artisan command:run的时候,我启用了一个线程(请求),在这个线程结束前,laravel不会清除内存呢?

还望站长解惑

国营 2021.07.16 03:08

在这种场景下,读取那么多json数据的时候,自己调用框架读写操作时肯定会急剧占用内存的,不要指望自动内存清理解决问题,必须要依赖手动清理内存unset,消耗比较大相关变量用完之后即可清理,这样就不会出问题了。

along 2021.07.16 04:55

谢谢站长,能unset的我都unset了,

在一个transcation中,循环100条语句,我只能在commit以后删除,那我到底该删除什么呢?和数据库的链接吗?

国营 2021.07.16 05:59

数据和代码发我邮箱,晚上有时间了我看看

国营 2021.07.22 01:04

抱歉这几天一直忙网站升级的事,一直没时间看你那个问题,再等我两天,网站新版本的很多工作都还没有完成。

along 2021.07.23 03:43

没事,

你忙你的,

我这个已经投入运营了.

网站升级的很棒,期待更多的功能.

国营 2021.07.23 06:13

新版出来之后大家一直在反馈问题,也遇到了过去从来没见过的奇奇怪怪的问题,由于开发环境和生产环境基础软件的版本不同,很多方案不得不重新设计,这几天也没怎么睡过,希望早点稳定下来,过了这个排错期,以后就可以增加功能了。原来的网站基于 5.6 的,现在太多曾经的开发包和工具都不能用了,添加功能实在不方便,必须要升级基础版本了,也尝试了一些新东西,新的开发模式,还是挺好玩的,恶心人的问题一个接一个,相比于过去传统的网站开发模式,我也算是积累了不少新经验。

wonsky87 2021.10.19 03:59

看得出来作者很用心去写了,赞。

国营 2021.10.19 06:10

欢迎常来Coding10做客,提出更多宝贵意见。

微信扫码登录