ThinkPHP框架使用的特性fastcgi_finish_request和trait

咔咔

咔咔

2020-12-29

2145人浏览

原创

本文会对控制器最后的执行流程和使用的俩个高级属性进行简单的学习,一个是fastcgi_finish_request方法巧用,另一个是trait特性,超类的概念多少都有过了解,接下来一起来解析一下。

一、如何输出数据到终端

当执行完控制器中的方法响应数据给App类的run方法,直到这里就已经执行完了。

是不是有点懵这里的数据最终会返回哪里呢!

image.png

之前写过的框架执行流程、路由、控制器实例化都是从这里开始进入的。

所以当run方法执行完成之后,就会把对应的结果给返回到这里。

image.png

这一部分的代码Container::get('app')应该都知道了是返回一个App类的实例。

然后通过App类去执行run方法,才会有之前讲过的一切。

下图是咔咔从半中腰做的一个思维导图,前面的没有,后边的所有知识点都会写在这个思维导图里。

image.png

执行完run方法就会去执行Container::get('app')->run()->send()send这个方法,有多少人会认为在App类里边执行send方法。

其实不是的,回想一下之前执行控制器方法然后返回的响应结果是什么?

如果你不是很粗略的看都会记得是Response的一个对象实例。

所以说send方法会去response类里边去执行。

image.png

先不看其它的,先看这行代码$this->app['hook'],现在知道是执行的那里吗?

这种形式就是通过访问数组形式去访问对象的属性,也就是之前解析的ArrayAccess这个类。当访问的属性不存在时会去执行offsetGet,然后执行魔术方法__get,最终通过make方法返回实例,这一切的操作都是在容器中。

对这行代码具体是监听的什么就不去做解析了。

接着需要看处理输出数据的这行代码$data = $this->getContent();

这个方法做的事情就是将传过来的数据赋值给本类的content属性。

image.png

其实在获取输出数据这个方法中,请看咔咔圈出来的第一个地方感觉是很没有必要。

可以看到根本对数据就没有任何的处理,只是简单的返回了,所以说框架有好的地方也有不好的地方,只有你去阅读了才会知道,否则你会对你经常使用的工具一无所知。

image.png

在接着就是Trace调试注入,就是通过配置文件配置的,通过调用debug类实现的,这里就不详解了。

然后就是缓存判断,缓存会在后文中单独拎出来讲,所以也是过。

在接下来就对响应头的设置了,检测 HTTP 头是否已经发送,这块的东西就很重要了,也是平时接触不多的知识点了。

  • headers_sent() : 检测 HTTP 头是否已经发送
  • http_response_code() :获取/设置响应的 HTTP 状态码
  • header : 函数向客户端发送原始的 HTTP 报头。

image.png

最后一步,来了来了,它来了,它带着echo来了,执行了一个方法$this->sendData($data);

给人一种媳妇熬成娘的感觉,终于来到的终点站,一个echo输出了咔咔几十天的心酸啊!

为了到达这个echo咔咔是经历九九八十一难啊!战斗还未停止,同志仍需努力啊!

image.png

那么到这里关于框架执行然后到应用初始化,在到路由检测、控制器的实例化、然后返回response实例,在通过入口文件执行send方法。

最后将数据输出到终端,也就是一个echo的事情。

虽然这里的战斗结束了,但是在下面还有一个非常重要的知识点,咔咔将重新提一节来进行说明。

二、fastcgi_finish_request方法巧用

在上一节中通过Container::get('app')->run()->send();在response类中执行了send方法,输出了数据。

但是在输出数据之后还执行了一个方法fastcgi_finish_request();,给的注释是提高页面响应,接下来好好来扒一扒其中的奥秘。

在PHP官网中看到这样一段话

The script will still occupy a FPM process after fastcgi_finish_request(). So using it excessively for long running tasks may occupy all your FPM threads up to pm.max_children. This will lead to gateway errors on the webserver.

在fastcgi_finish_request()之后,脚本仍将占用FPM进程。 因此,对于长时间运行的任务过度使用它可能会占用您的所有FPM线程,直到pm.max_children。 这将导致Web服务器上的网关错误。

所以说在没有彻底的了解这个方法之前不要轻易的在自己的项目中使用这个方法。

接下来咔咔将使用一个案例来演示这个方法的使用,仅仅只是演示使用,如果需要使用到项目中请仔细阅读文档应该注意的问题。

案例演示

公司有一个业务需要发送通知给用户,但是由于发送时间太久,非常费时间,有可能需要好几十秒的时间,更严重的会直接导致浏览器连接超时。

在一个问题就是用户体验的问题,用户等待时间过程,体验当然不好。

为了解决以上俩个问题,今天谈论的fastcgi_finish_request就派上了用场。

理解

对这个函数的理解其实就是发送响应给浏览器,用户等待时间大大缩短,但是PHP进程还是在运行的。

这样就达到了来个目的,就类似于我们经常说的异步执行。

直观的来说就是发送邮件有可能需要10秒,但是用户是没有感知的,用户点击发送邮件之后直接就返回发送成功,浏览器响应结束,用户做其它事情,后台进程继续执行发送邮件的任务。

案例

image.png

具体代码

<span style="display: block; background: url(" https: no-repeat rgb height: width: margin-bottom: border-radius:></span><code class="hljs" style="overflow-x: auto; padding: 15px 16px 16px; color: rgb(171, 178, 191); display: -webkit-box; font-family: " operator mono consolas monaco menlo monospace font-size: background: rgb border-radius:><span class="hljs-meta" style="color: rgb(97, 174, 238); line-height: 26px;"><?php </span><br><span class="hljs-comment" style="color: rgb(92, 99, 112); font-style: italic; line-height: 26px;">/**<br> * 设置超时时间,变成不限制<br> *<br> */</span><br>set_time_limit(<span class="hljs-number" style="color: rgb(209, 154, 102); line-height: 26px;">0</span>);<br><br><span class="hljs-comment" style="color: rgb(92, 99, 112); font-style: italic; line-height: 26px;">/**<br> * 本函数模拟非常耗时的任务,执行完毕需要5秒的时间<br> */</span><br><span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: rgb(198, 120, 221); line-height: 26px;">function</span> <span class="hljs-title" style="color: rgb(97, 174, 238); line-height: 26px;">writeFile</span><span class="hljs-params" style="line-height: 26px;">()</span><br></span>{<br>    $path = <span class="hljs-string" style="color: rgb(152, 195, 121); line-height: 26px;">'D:/phpstudy_pro/WWW/kaka.txt'</span>;<br>    file_put_contents($path,<span class="hljs-string" style="color: rgb(152, 195, 121); line-height: 26px;">'程序运行开始'</span> . PHP_EOL,FILE_APPEND);<br>    <span class="hljs-keyword" style="color: rgb(198, 120, 221); line-height: 26px;">for</span>($i =<span class="hljs-number" style="color: rgb(209, 154, 102); line-height: 26px;">0</span>;$i 5</span>;$i++) {<br>        file_put_contents($path,time() . PHP_EOL,FILE_APPEND);<br>        sleep(<span class="hljs-number" style="color: rgb(209, 154, 102); line-height: 26px;">1</span>);<br>    }<br><br>    file_put_contents($path,<span class="hljs-string" style="color: rgb(152, 195, 121); line-height: 26px;">'程序运行结束'</span> . PHP_EOL,FILE_APPEND);<br><br>}<br><br><span class="hljs-comment" style="color: rgb(92, 99, 112); font-style: italic; line-height: 26px;">/**<br> * 输出文字标记,任务开始<br> */</span><br><span class="hljs-keyword" style="color: rgb(198, 120, 221); line-height: 26px;">echo</span>(<span class="hljs-string" style="color: rgb(152, 195, 121); line-height: 26px;">'任务开始'</span>);<br><br><span class="hljs-comment" style="color: rgb(92, 99, 112); font-style: italic; line-height: 26px;">/**<br> *  后台执行非常耗时的任务<br> */</span><br>register_shutdown_function(writeFile);<br><br><span class="hljs-comment" style="color: rgb(92, 99, 112); font-style: italic; line-height: 26px;">/**<br> * 立即发送请求<br> */</span><br>fastcgi_finish_request();<br><br><br><br></code>

image.png

以上测试全部使用linux系统进行测试哈,否则你看不到直观的效果。

经过上面的演示,响应非常快,浏览器响应结束后,后台程序依然进行执行每秒执行一个时间戳。

以上就是对fastcgi_finish_request方法的简单介绍,如果你也感兴趣可以进行简单的尝试一下,有助于更好的去理解其中的小秘密。

三、trait特性讲解

应该在俩年前咔咔就对这个特性进行过一次解析,trait就是常说的超类。

这个特性是在PHP5.4才加入的,这个特性不是经常使用的接口更不是类。

这个特性是为了解决PHP的一大弱点只能单继承的缺点,但是也不能叫多继承,严谨一点的就是类似多继承的功能而已。

接下来给大家演示一个案例。

创建test文件一,并且返回对应类名。

image.png

ThinkPHP 8.1.0
ThinkPHP 8.1.0

ThinkPHP 8.1.0 正式发布,深度优化路由与验证机制,完美兼容 PHP 8.4。本版本修复了数组路由配置异常,新增枚举值校验与高级数组验证功能,支持路由分类默认处理。作为高性能 PHP 框架的最新迭代,它延续了简洁实用的设计原则,提供更稳定的底层架构与更流畅的开发体验,助力开发者快速构建现代化 Web 应用与企业级系统。

下载

创建test1文件,并且返回对应类名

image.png

创建控制器文件用来输出信息。

image.png

然后在控制器中引入对应的超类文件,这里需要注意的是圈住的第一个框,这个框就是直接引入超类test文件。

image.png

然后可以直接进行访问,看会返回什么。

image.png

通过上图访问结果结果可以看得到返回的是Test超类文件的方法,但是此控制器同样也基础了Controller控制器,这也就是在文章一开头就说的超类就是实现了一种多继承的功能而已。

但是这里会存在一个问题,请看下图报错信息。

image.png

上图的报错信息是因为在控制器中使用了俩个超类导致的,也就是下图的使用方式。

image.png

那么如何解决这种报错信息呢!接下来跟这咔咔的节奏一起来。

解决报错信息

在解决之前问题之前得先清楚这个问题是由于什么引起的。

出现这个错误的原因是引用的两个trait里面有同名的hello函数,出现了冲突。

但是在日常开发中这种情况都是可以避免的,因为手动改方法名还是很方便的,但是这里咔咔教大家如何解决这种问题。

一是用其中一个trait里的hello方法覆盖另外一个trait的同名方法,因为两个方法内容是一致的,所以我这里直接选择insteadof覆盖;

二是给他们用as起别名,这样就不会有冲突了。as关键词还有另外一个用途,那就是修改方法的访问控制。

image.png

经过上图的改动之后,再一次的进行访问,看一下返回结果。

image.png

那么这个时候就会有伙伴有疑问了,就是案例打印结果一直是Test类的方法,Test1类的方法一直没有进行打印。

那是如何进行访问的呢!来接着看一下。

image.png

从上图可以看到将访问方法改为了别名控制访问,接着来看一下访问结果。

image.png

从上图中可以可以看到返回结果就是超类Test1类的返回结果。

那么关于as这个的使用就需要大家在去搜索一下使用方式,有时候注意一下细节就可以学到很多知识点。

总结

直到这里关于控制器的源码解析就到这了,咔咔通过源码给大家分析控制器的如如何进行实例化的。

也再一次的进行了对ArrayAccess和魔术方法的调用关系,一定要有自己的思考去想问题。

在就是对访问控制器后是如何进行响应数据的,等等。

也在源码中学到了关于fastcgi_finish_request方法巧用,但是在使用这个函数一定要注意关于咔咔提到的俩个注意点。

最后就是对超类的一个简单案例描述。

坚持学习、坚持写博、坚持分享是咔咔从业以来一直所秉持的信念。希望在偌大互联网中咔咔的文章能带给你一丝丝帮助。我是咔咔,下期见。

php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

thinkphp

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
504 gateway timeout怎么解决
504 gateway timeout怎么解决

504 gateway timeout的解决办法:1、检查服务器负载;2、优化查询和代码;3、增加超时限制;4、检查代理服务器;5、检查网络连接;6、使用负载均衡;7、监控和日志;8、故障排除;9、增加缓存;10、分析请求。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.11.27

750

4

default gateway怎么配置
default gateway怎么配置

配置default gateway的步骤:1、了解网络环境;2、获取路由器IP地址;3、登录路由器管理界面;4、找到并配置WAN口设置;5、配置默认网关;6、保存设置并退出;7、检查网络连接是否正常。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.12.07

295

5

thinkphp和laravel哪个简单
thinkphp和laravel哪个简单

对于初学者来说,laravel 的入门门槛较低,更易上手,原因包括:1. 更简单的安装和配置;2. 丰富的文档和社区支持;3. 简洁易懂的语法和 api;4. 平缓的学习曲线。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.10

1589

7

thinkphp性能怎么样
thinkphp性能怎么样

thinkphp 是一款高性能的 php 框架,具备缓存机制、代码优化、并行处理和数据库优化等优势。官方性能测试显示,它每秒可处理超过 10,000 个请求,实际应用中被广泛用于京东商城、携程网等大型网站和企业系统。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.10

754

7

ThinkPHP6后台管理系统开发与RBAC权限控制实践
ThinkPHP6后台管理系统开发与RBAC权限控制实践

本专题围绕 ThinkPHP6 在后台管理系统开发中的应用展开,重点讲解基于 RBAC 模型的权限控制实现方案。内容涵盖管理员角色设计、菜单权限分配、接口鉴权、中间件拦截机制以及后台模块化开发思路。同时结合实际案例,讲解如何构建完整的后台管理系统,包括用户管理、权限管理与操作日志记录,帮助开发者搭建安全、可扩展的企业级后台系统。

2026.03.20

101

14

ThinkPHP API接口开发与前后端分离实战
ThinkPHP API接口开发与前后端分离实战

本专题围绕ThinkPHP在前后端分离项目中的 API 开发展开,系统讲解 RESTful 接口设计规范、统一返回结构、参数验证与异常处理机制。内容涵盖 Token 鉴权、跨域处理、接口版本管理以及接口文档生成方案。通过完整项目案例,帮助开发者构建规范、高效、易维护的后端接口服务体系。

2026.03.20

181

14

ThinkPHP ORM模型关系与数据库操作优化实践
ThinkPHP ORM模型关系与数据库操作优化实践

本专题聚焦ThinkPHP中 ORM 模型的高级用法与数据库操作优化技巧。内容包括一对一、一对多、多对多关系定义与使用、关联预加载、查询构建器优化以及复杂查询封装方法。同时结合实际业务场景,讲解如何避免 N+1 查询问题、提升数据库访问效率,帮助开发者编写高性能的数据访问层代码。

2026.03.20

91

18

ThinkPHP模型详解
ThinkPHP模型详解

本专题整合了ThinkPHP模型相关内容,阅读专题下面的文章了解更多详细介绍。

2026.03.26

91

27

ThinkPHP表单验证与数据安全处理实战
ThinkPHP表单验证与数据安全处理实战

本专题聚焦 ThinkPHP 在表单处理中的验证与安全机制,系统讲解验证器使用、自定义规则、场景验证以及错误提示处理。内容涵盖 XSS 防护、SQL 注入防御、数据过滤与输入校验等关键安全措施。通过实际案例,帮助开发者构建安全可靠的数据处理流程。

2026.03.30

96

20

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程